#ifndef __LOGGER_H__                                                           
#define __LOGGER_H__

#include <iostream>
#include <vector>
#include <string>
#include <sstream>


#define _LOG_HEADER_NUM_ 6 //defined header number
#define _LOG_HEADER_L0_ "[]" //none
#define _LOG_HEADER_L1_ "[Info]" //ingomation
#define _LOG_HEADER_L2_ "[Data]" //data
#define _LOG_HEADER_L3_ "[Warning]" //warning
#define _LOG_HEADER_L4_ "[Error]" //error
#define _LOG_HEADER_L5_ "[Debug]" //debug

extern const int  _num_of_log_header;
extern const int  _debug_log_header_id;


//Define log level
class LogLevel{ //{{{
public:
   std::string header;
   std::string txt;
   short id;

   std::string log_id;
   std::string log_date;
   std::string log_txt;

   virtual ~LogLevel(){};
   LogLevel(void){
      header = "";
      txt = "";
      id = 0;

      log_id = "";
      log_date = "";
      log_txt = "";
   }

   int set_log( std::string s_id , std::string s_date , std::string s_log , std::string s_func ="" , short mode = 0){
      log_id += s_id;log_id += "\n";
      log_date += s_date;log_date += "\n";
      log_txt+= s_log;log_txt += "\n";

      std::string buf ="";buf += s_id;buf += s_date;
      buf += header;buf += "[";buf += s_func;buf += "] ";
      buf += s_log;buf += "\n";

      txt += buf;
      id++;

      if( mode )std::cout << buf;

      return 1;
   }

   std::string set_header( short log_level ){ 
      switch( log_level ){
         case 0:
            header = _LOG_HEADER_L0_ ;
            break;
         case 1:
            header = _LOG_HEADER_L1_ ;
            break;
         case 2:
            header = _LOG_HEADER_L2_ ;
            break;
         case 3:
            header = _LOG_HEADER_L3_ ;
            break;
         case 4:
            header = _LOG_HEADER_L4_ ;
            break;
         case 5:
            header = _LOG_HEADER_L5_ ;
            break;
      };
      return header;
   }

}; //}}}


//Logger 
class Logger{
private:
   LogLevel *log_lv[_LOG_HEADER_NUM_];

   short print_mode; //0:No print , 1:print all log , 2:print all log without data
   short debug_id;
   std::string function_name;

   std::string GetDate( void );
   std::string Int2String( int i );
   std::string Short2String( short i );
   std::string Float2String( float i );
   std::string Double2String( double i );
   std::string Long2String( long i );
   std::vector<std::string> split(std::string str, std::string delim);

public:
   Logger( short mode = 1 );
   virtual ~Logger(){};

   //File Setting 
   int SetFunction( std::string function , int log_level = 1 , int print = 0 );

   //Write file 
   int Log( std::string log , short log_level = 1 );
   int Log( int log , short log_level = 1 );
   int Log( short log , short log_level = 1 );
   int Log( float log , short log_level = 1 );
   int Log( double log , short log_level = 1 );
   int Log( long log , short log_level = 1 );

   int Debug( std::string log );

   int Clear( void );

   //Read file 
   int Read( std::string input_name );
   int GetSize( short log_level = 0 );


   //Output file 
   int Print( short log_level = 0 ); // 0:All,1:Info,2:Data,3:Warning,4:Error
   int Write( std::string output_file , short log_level = 0 , short write_mode = 0 , short log_num = 0 ); //Output file , writemode 0:overwrite 1:add
   std::string GetLogString( short log_level = 0 , short log_num = 0); //log_num 0: all , 1:id , 2: date , 3: text

};

#endif //__LOGGER_H__
