#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <time.h>
#include "MyLogger.h"


MyLogger::MyLogger( short mode ){ //{{{

   print_mode = mode;

   log_l1 = "";
   log_l2 = "";
   log_l3 = "";
   log_l4 = "";
   log_l5 = "";

   function_name = "No Function";

   log_id = 0;
   debug_id = 0;
} //}}}


//-- Public Function --//

int MyLogger::Log( std::string log , short log_level ){ //{{{

   std::string buf = "[";buf += Int2String( log_id );buf += "] ";
   buf += GetDate();
   buf += " ";
   buf += GetHeader( log_level );
   buf += "[";buf += function_name;buf += "] ";
   buf += log;
   buf += ( log_level != 2) ? "\n" : "";

   switch( log_level ){
      case 0:
         log_l0 += buf;
         break;
      case 1:
         log_l0 += buf;
         log_l1 += buf;
         break;
      case 2:
         buf = "";buf += log;
         log_id--;

         log_l0 += buf;
         log_l2 += buf;
         break;
      case 3:
         log_l0 += buf;
         log_l3 += buf;
         break;
      case 4:
         log_l0 += buf;
         log_l4 += buf;
         break;
      case 5:
         log_l0 += buf;
         log_l5 += buf;
         debug_id++;
         break;
   };

   if( print_mode ){
      std::cout << buf;
   }

   log_id++;

   return 1;
}

int MyLogger::Log( int log , short log_level ){
   Log( Int2String( log ) , log_level );
   return 1;
}
int MyLogger::Log( short log , short log_level ){
   Log( Short2String( log ) , log_level );
   return 1;
}
int MyLogger::Log( float log , short log_level ){
   Log( Float2String( log ) , log_level );
   return 1;
}
int MyLogger::Log( double log , short log_level ){
   Log( Double2String( log ) , log_level );
   return 1;
}
int MyLogger::Log( long log , short log_level ){
   Log( Long2String( log ) , log_level );
   return 1;
}//}}}

int MyLogger::Debug( std::string log ){ //{{{
   std::stringstream ss;
   ss << "Debug#(" << debug_id << "):" << log;

   std::string str;ss >> str;

   Log( str , 5 );
   return 1;
}//}}}

int MyLogger::SetFunction( std::string function , int log_level ){ //{{{
   function_name = function;

   std::string str = "** Function <";str += function_name;str += "> **";
   Log( str , log_level );

   return 1;
} //}}}

int MyLogger::Print( short log_level ){ // 0:All,1:Info,2:Data,3:Warning,4:Error {{{

   switch( log_level ){
      case 0:
         std::cout << log_l0;
         break;
      case 1:
         std::cout << log_l1;
         break;
      case 2:
         std::cout << log_l2;
         break;
      case 3:
         std::cout << log_l3;
         break;
      case 4:
         std::cout << log_l4;
         break;
   };

   return 1;
} //}}}

int MyLogger::Write( std::string output_file , short log_level ){ //Output file  {{{

   std::ofstream ofs( output_file.c_str() );

   switch( log_level ){
      case 0:
         ofs << log_l0;
         break;
      case 1:
         ofs << log_l1;
         break;
      case 2:
         ofs << log_l2;
         break;
      case 3:
         ofs << log_l3;
         break;
      case 4:
         ofs << log_l4;
         break;
   };

   ofs.close();

   return 1;
} //}}}


//-- Private Function --//

std::string MyLogger::GetHeader( short log_level ){ //{{{
   std::string str ;
   switch( log_level ){
      case 0:
         str = (std::string)_HEADER_L0_ ;
         break;
      case 1:
         str = (std::string)_HEADER_L1_ ;
         break;
      case 2:
         str = (std::string)_HEADER_L2_ ;
         break;
      case 3:
         str = (std::string)_HEADER_L3_ ;
         break;
      case 4:
         str = (std::string)_HEADER_L4_ ;
         break;
      case 5:
         str = (std::string)_HEADER_L5_ ;
         break;
   };
   return str;
} //}}}


std::string MyLogger::GetDate( void ){ //{{{

   struct tm *date;
   time_t now;
   int year, month, day;
   int hour, minute, second;

   time(&now);
   date = localtime(&now);

   year = date->tm_year + 1900;
   month = date->tm_mon + 1;
   day = date->tm_mday;
   hour = date->tm_hour;
   minute = date->tm_min;
   second = date->tm_sec;

   std::stringstream ss;
   ss <<  year << "/" << month << "/" << day << "_" << hour << ":" << minute << ":" << second ;
   std::string str;ss >> str ;

   return str;
} //}}}


std::string MyLogger::Int2String( int i ){ //{{{
   std::stringstream ss;ss << i ;
   std::string str;ss >> str ;
   return str;
}
std::string MyLogger::Short2String( short i ){ 
   std::stringstream ss;ss << i ;
   std::string str;ss >> str ;
   return str;
}
std::string MyLogger::Float2String( float i ){ 
   std::stringstream ss;ss << i ;
   std::string str;ss >> str ;
   return str;
}
std::string MyLogger::Double2String( double i ){ 
   std::stringstream ss;ss << i ;
   std::string str;ss >> str ;
   return str;
}
std::string MyLogger::Long2String( long i ){ 
   std::stringstream ss;ss << i ;
   std::string str;ss >> str ;
   return str;
}//}}}
