/***************************************************************************
 *   Copyright (C) 2004 by yunfan                                          *
 *   yunfan_zg@163.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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "evaimsend.h"
#include "evadefines.h"
#include <time.h>
#include <string.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <arpa/inet.h>
#endif

SendIM::SendIM(short type)
	: OutPacket(QQ_CMD_SEND_IM, true),
	receiver(0),
	face(0),
	contentType(type)
{
}

SendIM::SendIM(const SendIM &rhs)
	: OutPacket(rhs)
{
	receiver = rhs.getReceiver();
	face = rhs.getFaceCode();
	contentType = rhs.getContentType();
}

SendIM &SendIM::operator=(const SendIM &rhs)
{
	*((OutPacket *)this) = (OutPacket)rhs;
	receiver = rhs.getReceiver();
	face = rhs.getFaceCode();
	contentType = rhs.getContentType();
        return *this;	
}

int SendIM::putBody(unsigned char *buf) 
{
	int pos=0;
	int qqid = htonl(getQQ());  // method getQQ() from parent class
	// bit 0-3 sender
	memcpy(buf, &qqid, 4);
	pos+=4;	
	// bit 4-7 receiver
	int tmpReceiver = htonl(receiver);
	memcpy(buf+pos, &tmpReceiver, 4);
	pos+=4;
	
	//  bit 8-9 qq client version
	short tmpVersion = htons(version);
	memcpy(buf+pos, &tmpVersion, 2);
	pos+=2;
	
	// bit 10-13 sender again
	memcpy(buf+pos, &qqid, 4);
	pos+=4;
	
	// bit 14-17 receiver
	memcpy(buf+pos, &tmpReceiver, 4);
	pos+=4;
	
	// bit 18-33 file transfer session key
	memcpy( buf+pos, getFileSessionKey(), QQ_KEY_LENGTH);
	pos+=QQ_KEY_LENGTH;
	
	// bit 34-35 contents type ( is it normal text message or file transfer...)
	short tmpCType = htons(contentType);
	memcpy(buf+pos,&tmpCType ,2);
	pos+=2;
	
	// sequence number
	short tmpSeq = htons(sequence);
	memcpy(buf+pos, &tmpSeq,2);
	pos+=2;	
		
	// sending time
	//uint time = QDateTime::currentDateTime(Qt::LocalTime).toTime_t();
	time_t now;
	now = time(NULL);
	uint tmpTime = htonl(now);
	memcpy(buf+pos, &tmpTime, 4);
	pos+=4;

	short tmpFace = htons(face);
	memcpy(buf+pos, &tmpFace,2);
	pos+=2;
	
	memset(buf+pos, 0, 3);
	pos+=3;
	
	// font information, set as 1
	buf[pos++] = 0x01;
	memset(buf+pos, 0, 4);
	pos+=4;
	
	pos+= putContents(buf+pos);  // put all contents in
	return pos;
} 

int SendIM::putContents(unsigned char *buf)
{
	fprintf(stderr, "In SendIM\n");
	buf[0]=0;
	return 0;
}

/*  ======================================================= */

SendTextIMPacket::SendTextIMPacket()
	: SendIM(QQ_IM_NORMAL_TEXT),
	encoding(QQ_IM_ENCODING_GB),
	red(0),green(0),blue(0),
	bold(false),italic(false),underline(false),
	fontSize(0x09),
	fontFlag(0x09),
	message("Hello, I am using Eva."),
	replyType(QQ_IM_NORMAL_REPLY)
{
	char *fname = (char *)malloc(5);
        fname[0] = 0xcb;
	fname[1] = 0xce;
	fname[2] = 0xcc;
        fname[3] = 0xe5;
	fname[4] = 0x00;
	fontName = fname; // just set font name to "Song Ti" in Chinese
	free(fname);
}

SendTextIMPacket::SendTextIMPacket(const SendTextIMPacket &rhs)
	: SendIM(rhs)
{
	encoding = rhs.getEncoding();  
	fontName = rhs.getFontName();
	
	red = rhs.getRed();
	green = rhs.getGreen();
	blue = rhs.getBlue();
		
	fontFlag = 0x00;
	bold = rhs.isBold(); 
	fontFlag |= bold ? 0x20 : 0x00; 
	
	italic = rhs.isItalic(); 
	fontFlag |= italic ? 0x40 : 0x00;
	
	underline = rhs.isUnderline();
	fontFlag |= underline ? 0x80 : 0x00;
	
	fontSize = rhs.getFontSize();
	fontFlag |= fontSize;
	
	message = rhs.getMessage();      
	replyType = rhs.getReplyType(); 
}

SendTextIMPacket &SendTextIMPacket::operator=(const SendTextIMPacket &rhs)
{
	*((SendIM *)this) = (SendIM)rhs;
	encoding = rhs.getEncoding();  
	fontName = rhs.getFontName();
	
	red = rhs.getRed();
	green = rhs.getGreen();
	blue = rhs.getBlue();
		
	fontFlag = 0x00;
	bold = rhs.isBold(); 
	fontFlag |= bold ? 0x20 : 0x00; 
	
	italic = rhs.isItalic(); 
	fontFlag |= italic ? 0x40 : 0x00;
	
	underline = rhs.isUnderline();
	fontFlag |= underline ? 0x80 : 0x00;
	
	fontSize = rhs.getFontSize();
	fontFlag |= fontSize;
	
	message = rhs.getMessage();      
	replyType = rhs.getReplyType(); 
        return *this;
}

void SendTextIMPacket::setBold(bool bold) 
{
	this->bold = bold;
	fontFlag &= 0xDF;
	fontFlag |= bold ? 0x20 : 0x00;
}
 
void SendTextIMPacket::setItalic(bool italic) 
{
	this->italic = italic;
	fontFlag &= 0xBF;
	fontFlag |= italic ? 0x40 : 0x00;
}
	 
void SendTextIMPacket::setUnderline(bool underline) 
{
	this->underline = underline;
	fontFlag &= 0x7F;
	fontFlag |= underline ? 0x80 : 0x00;
}
    
void SendTextIMPacket::setFontSize(char fontSize) 
{
	this->fontSize = fontSize;
	fontSize &= 0x1F;
	fontFlag &= 0xE0;
	fontFlag |= fontSize;
}

void SendTextIMPacket::setAutoReply(const bool isNormal)
{
	if(isNormal)
		replyType = QQ_IM_NORMAL_REPLY;
	else
		replyType = QQ_IM_AUTO_REPLY;
}

int SendTextIMPacket::putContents(unsigned char *buf) 
{
	int pos=0;
	buf[pos++] = replyType; // auto-reply or not
	
	std::string str2send = EvaUtil::convertToSend(message);
	memcpy(buf+pos, str2send.c_str(), str2send.length());
	pos += str2send.length();

	buf[pos++] = 0x20; //  a space
	buf[pos++] = 0x00;    //  C style string terminator
	
	buf[pos++] = fontFlag;
	buf[pos++] = red;
	buf[pos++] = green;
	buf[pos++] = blue;
	
	buf[pos++] = 0;
	
	short tmpEncoding = htons(encoding);  // encoding for text
	memcpy(buf+pos,&tmpEncoding, 2);
	pos+=2;
	
	int len = fontName.length();     // font name
	memcpy(buf+pos, fontName.c_str(), len);
        pos+=len;
        
	buf[pos++] = 0x0D;   // an Enter
	
	return pos;
}
/*
std::string SendTextIMPacket::convertToSend(const std::string &text)
{
	std::string converted = "";
	int offset=0;
	char smileyTag = 0x14;
	for(uint i=0; i< text.length(); i++){
		if(text[i] == '/'){
			offset = i;
			while(text[offset] != 0x00 && text[++offset]!=' ');
			if((offset - i)<8){
				char code = util.textToSmiley(text.substr(i,offset-i));
				if(code){
					converted += smileyTag;
					converted += code;
					i=offset;
					continue;
				}
			}
			converted+=text[i];
			continue;
		}
		converted+=text[i];
	}
	return converted;
}*/

/* =========================================================== */

SendIMReplyPacket::SendIMReplyPacket(unsigned char *buf, int len)
	: InPacket(buf, len),
	replyCode(0x01)
{
}

SendIMReplyPacket::SendIMReplyPacket(const SendIMReplyPacket &rhs)
	: InPacket(rhs)
{
	replyCode = rhs.getReplyCode();
}

SendIMReplyPacket &SendIMReplyPacket::operator=(const SendIMReplyPacket &rhs )
{
	*((InPacket *)this) = (InPacket)rhs;
	replyCode = rhs.getReplyCode();
        return *this;
}

const bool SendIMReplyPacket::isSentOK() const
{
	 return replyCode == QQ_SEND_IM_REPLY_OK;
}

void SendIMReplyPacket::parseBody()
{
	replyCode = decryptedBuf[0];
}

