// client_data.cpp
//
// A Container Class for CallCommander Client Data
//
//   (C) Copyright 2002-2006 Fred Gleason <fredg@paravelsystems.com>
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as
//   published by the Free Software Foundation; either version 2 of
//   the License, or (at your option) any later version.
//
//   This program 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 General Public License for more details.
//
//   You should have received a copy of the GNU General Public
//   License along with this program; if not, write to the Free Software
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//

#define _BSD_SOURCE
#include <time.h>
#include <stdio.h>

#ifdef WIN32
#include <windows.h>
#endif  // WIN32

#include <QtGui/QMessageBox>

#include "client_data.h"

ClientData::ClientData()
{
  clear();
}


QString ClientData::userName() const
{
  return client_user_name;
}


void ClientData::setUserName(const QString &username)
{
  client_user_name=username;
}


QHostAddress ClientData::ipAddress() const
{
  return client_ip_address;
}


void ClientData::setIpAddress(QHostAddress addr)
{
  client_ip_address=addr;
}


Q_UINT16 ClientData::tcpPort() const
{
  return client_tcp_port;
}


void ClientData::setTcpPort(Q_UINT16 port)
{
  client_tcp_port=port;
}


QDateTime ClientData::loginDateTime() const
{
  struct tm *tm=localtime(&client_login_time);
  QDateTime datetime(QDate(tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday),
		     QTime(tm->tm_hour,tm->tm_min,tm->tm_sec));

/*
  tm=gmtime(&client_login_time);
  QDateTime gm_datetime(QDate(tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday),
			QTime(tm->tm_hour,tm->tm_min,tm->tm_sec));
  QMessageBox::information(NULL,"DEBUG",QString().
  sprintf("ClientData::loginDateTime() -- Local: %s  GMT: %s\n",
	 (const char *)datetime.toString("MM/dd/yyyy - hh:mm:ss"),
	 (const char *)gm_datetime.toString("MM/dd/yyyy - hh:mm:ss")));
*/
  return datetime;
}


void ClientData::setLoginDateTime(QDateTime datetime)
{
  client_login_time=datetime.toTime_t();
}


QString ClientData::consoleName() const
{
  return client_console_name;
}


void ClientData::setConsoleName(const QString &name)
{
  client_console_name=name;
}


QString ClientData::location() const
{
  return client_location;
}


void ClientData::setLocation(const QString &name)
{
  client_location=name;
}


ConsoleData::Mode ClientData::consoleMode() const
{
  return client_console_mode;
}


void ClientData::setConsoleMode(ConsoleData::Mode mode)
{
  client_console_mode=mode;
}


ClientData::ClientType ClientData::clientType() const
{
  return client_client_type;
}


void ClientData::setClientType(ClientData::ClientType type)
{
  client_client_type=type;
}


QDateTime ClientData::lastKeepalive() const
{
  return client_last_keepalive;
}


void ClientData::setLastKeepalive(const QDateTime &datetime)
{
  client_last_keepalive=datetime;
}


int ClientData::version() const
{
  return client_version;
}


QString ClientData::versionString() const
{
  return QString().sprintf("%d.%d.%d",
			   0xFF&(client_version>>16),
			   0xFF&(client_version>>8),
			   0xFF&client_version);
}


void ClientData::setVersion(int ver)
{
  client_version=ver;
}


void ClientData::setVersion(const QString &ver)
{
  int left=ver.find(".");
  int right=ver.findRev(".");
  int first=ver.left(left).toInt();
  QString str=ver.left(right);
  int second=str.right(str.length()-left-1).toInt();
  int third=ver.right(ver.length()-right-1).toInt();

  client_version=((0xFF&first)<<16)+((0xFF&second)<<8)+(0xFF&third);
}


bool ClientData::load(const QString &buffer)
{
  QDateTime datetime;
  QString str;
  unsigned field=0;
  bool ok=false;

  // printf("ClientData::load() - READING: %s\n",(const char *)buffer);

  clear();
  client_version=0;
  for(unsigned i=0;i<buffer.length();i++) {
    if(((const char *)buffer)[i]=='|') {
      switch(field) {
	  case 1:  // IP Address
	    client_ip_address.setAddress(str);
	    if(client_ip_address.isNull()) {
	      printf("ClientData::load() - ERR1\n");
	      return false;
	    }
	    break;

	  case 2:  // TCP Port
	    client_tcp_port=str.toUInt(&ok);
	    if(!ok) {
	      printf("ClientData::load() - ERR2\n");
	      return false;
	    }
	    break;

	  case 3:  // Login DateTime
	    datetime=
	      QDateTime(QDate(str.left(4).toInt(),str.mid(5,2).toInt(),
			      str.mid(8,2).toInt()),
			QTime(str.mid(11,2).toInt(),str.mid(14,2).toInt(),
			      str.right(2).toInt()));
	    if(!datetime.isValid()) {
	      printf("ClientData::load() - ERR3\n");
	      return false;
	    }
	    client_login_time=
	      QDateTime(QDate(1970,1,1),QTime(0,0,0)).secsTo(datetime);
	    break;

	  case 5:  // Console Mode
	    client_console_mode=(ConsoleData::Mode)str.toUInt(&ok);
	    if(!ok) {
	      printf("ClientData::load() - ERR4\n");
	      return false;
	    }
	    break;

	  case 6:  // Client Type
	    client_client_type=(ClientData::ClientType)str.toUInt(&ok);
	    if(!ok) {
	      printf("ClientData::load() - ERR5\n");
	      return false;
	    }
	    break;
      }
      str="";
      field++;
    }
    else {
      switch(field) {
	  case 0:  // User Name
	    client_user_name+=buffer.at(i);
	    break;
	    
	  case 1:  // IP Address
	  case 2:  // TCP Port
	  case 3:  // Login DateTime
	  case 5:  // Console Mode
	  case 6:  // Client Type
	  case 8:  // Client Version
	    str+=buffer.at(i);
	    break;
	    
	  case 4:  // Console Name
	    client_console_name+=buffer.at(i);
	    break;

	  case 7:  // Location (Studio Name)
	    client_location+=buffer.at(i);
	    break;

	  default:
	    return false;
      }
    }
  }
  if(field==7) {
    return true;
  }
  if(field==8) {
    client_version=str.toInt();
    return true;
  }
  return false;
}


QString ClientData::save() const
{
  struct tm *tm=gmtime(&client_login_time);
  return QString().sprintf(
    "%s|%s|%u|%04d-%02d-%02d %02d:%02d:%02d|%s|%u|%u|%s|%d",
    (const char *)client_user_name,
    (const char *)client_ip_address.toString(),
    client_tcp_port,
    tm->tm_year+1900,
    tm->tm_mon+1,
    tm->tm_mday,
    tm->tm_hour,
    tm->tm_min,
    tm->tm_sec,
    (const char *)client_console_name,
    client_console_mode,
    client_client_type,
    (const char *)client_location,
    client_version);
}


void ClientData::clear()
{
  client_user_name="";
  client_ip_address.setAddress("127.0.0.1");
  client_tcp_port=0;
  client_login_time=0;
  client_console_name="";
  client_location="";
  client_console_mode=ConsoleData::Unavailable;
  client_client_type=ClientData::TypeUnknown;
  client_last_keepalive=QDateTime();
  setVersion(VERSION);
}


QString ClientData::clientText(ClientData::ClientType type)
{
  QString str;
  switch(type) {
      case ClientData::TypeUnknown:
	str="Unknown";
	break;

      case ClientData::TypeUser:
	str="User";
	break;

      case ClientData::TypeCidMonitor:
	str="CallerID Monitor";
	break;

      case ClientData::TypeAudioRecorder:
	str="Audio Recorder";
	break;

      case ClientData::TypeLogicModule:
	str="Logic Module";
	break;
  }
  return str;
}
