/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          clogfile.cpp  -  description
                             -------------------
    begin                : Fri Jul 20 2001
    copyright            : (C) 2001-2005 by Alexey Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library is free software; you can redistribute it and/or modify it 
   under the terms of the GNU Library General Public License as published by
   the Free Software Foundation; either version 2 of the License, or (at 
   your option) any later version.

   This library is distributed in the hope that it will be useful, but 
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
   General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <sptk3/CLogFile.h>
#include <sptk3/CDateTime.h>

using namespace std;

CLogFile::CLogFile(string logfile,bool autoFlush,bool act) {
   m_filename = logfile;
   m_file = NULL;
   m_autoflush = autoFlush;
   m_active = act;
}

CLogFile::~CLogFile() {
   if (m_file) {
      try {
         fclose(m_file);
      }
      catch (...) {}
   }
}

bool CLogFile::checkOpen() {
   if (!m_file)
      m_file = fopen(m_filename.c_str(),"a+t");
   if (!m_file) {
      m_active = false;
      throw CException("Can't open log file "+m_filename);
   }
   return true;
}

void CLogFile::printTime() {
   CDateTime	dt(CDateTime::Now());

   if (!checkOpen()) return;
   if (m_active) 
      fprintf(m_file,"%s %s ",dt.dateString().c_str(),dt.timeString().c_str());
}

void CLogFile::writeString(string str) {
   if (!m_active) return;
   string error;
   lock(); 
   try {
      checkOpen();
      
      CStrings sl(str,"\n");
      for (unsigned i = 0; i < sl.size(); i++) {
         printTime();
         fprintf(m_file,"%s\n",sl[i].c_str());
      }
      if (m_autoflush) fflush(m_file);
   }
   catch (exception& e) {
      error = e.what();
   }
   catch (...) {
      error = "Unknown error";
   }
   unlock();
   if (!error.empty())
      throw CException(error+ " in CLogFile");
}

void CLogFile::writeBinaryBuffer(const char *label,const void *data,int len,bool printCheckSum) {
   if (!m_active) return;
   int unsigned checkSum = 0;
   if (len < 1) return;
   string error;
   int   labelLength = strlen(label);
   char *buffer = new char[ len * 3 + labelLength + 3 ];
   sprintf(buffer,"%s: ",label);

   lock(); 
   try {
      printTime();
      char *ptr = buffer + labelLength + 2;
      for (int i = 0; i < len; i++) {
         unsigned char ch = *((unsigned char *)data+i);
         sprintf(ptr,"%02x ",(unsigned)ch);
         checkSum += ch;
         ptr += 3;
      }
      *ptr = 0;
      if (printCheckSum)
         fprintf(m_file,"CS=%x SZ=%i bytes,  %s\n",checkSum,len,buffer);
      else  fprintf(m_file,"SZ=%i bytes,  %s\n",len,buffer);
      if (m_autoflush)
         fflush(m_file);
   }
   catch (exception& e) {
      error = e.what();
   }
   catch (...) {
      error = "Unknown error";
   }
   unlock();
   delete buffer;
   if (!error.empty())
      throw CException(error+ " in CLogFile");
}

void CLogFile::reset() {
   if (!m_active) return;
   if (m_file)
      fclose(m_file);
   m_file = fopen(m_filename.c_str(),"w+t");
}

void CLogFile::flush() {
   if (!m_active) return;
   fflush(m_file);
}

void CLogFile::active(bool act) {
   m_active = act;
   if (!m_active && m_file)
      fclose(m_file);
}
