/***************************************************************************
 *   Copyright (C) 2005 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 "evaaddfriend.h"
#include "evadefines.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <arpa/inet.h>
#endif

AddFriendPacket::AddFriendPacket( )
	: OutPacket(),
	qqNum(0)
{
}

AddFriendPacket::AddFriendPacket( const int id )
	: OutPacket(QQ_CMD_ADD_FRIEND, true),
	qqNum(id)
{
}

AddFriendPacket::AddFriendPacket(const AddFriendPacket &rhs)
	: OutPacket(rhs)
{
	qqNum = rhs.getAddQQ();
}


AddFriendPacket & AddFriendPacket::operator =( const AddFriendPacket & rhs )
{
	*( (OutPacket *)this) = (OutPacket)rhs;
	qqNum = rhs.getAddQQ();
	return *this;
}

int AddFriendPacket::putBody( unsigned char * buf )
{
	if(qqNum==0) return 0;
	char strID[20];
	sprintf(strID,"%d", qqNum);
	int len = strlen(strID);
	memcpy(buf, strID, len);
	return len;
}

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

AddFriendReplyPacket::AddFriendReplyPacket(unsigned char* buf, int len)
	: InPacket(buf, len)
{
}

AddFriendReplyPacket::AddFriendReplyPacket( const AddFriendReplyPacket &rhs)
	: InPacket(rhs)
{
	replyCode = rhs.getReplyCode();
	myQQ = rhs.getMyQQ();
}

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

void AddFriendReplyPacket::parseBody()
{
	int index=0;			
	while(decryptedBuf[index++] != 0x1f);
#ifdef WIN32
	char* qqstr; qqstr=(char*)_alloca(index+1);
#else
	char qqstr[index+1];
#endif
	memcpy(qqstr, decryptedBuf, index);
	qqstr[index]=0x00;		
	myQQ = atoi(qqstr);
	replyCode = decryptedBuf[index] - 0x30;
}

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

AddFriendAuthPacket::AddFriendAuthPacket( )
	: OutPacket( QQ_CMD_ADD_FRIEND_AUTH, true),
	message("")
{
}

AddFriendAuthPacket::AddFriendAuthPacket( const int id , const uint8_t type )
	: OutPacket( QQ_CMD_ADD_FRIEND_AUTH, true),
	type(type),
	buddyQQNum(id),
	message("")
{
}

AddFriendAuthPacket::AddFriendAuthPacket( AddFriendAuthPacket & rhs )
	: OutPacket(rhs)
{
	type = rhs.getType();
	buddyQQNum = rhs.getBuddyQQ();
	message = rhs.getMessage();
}

AddFriendAuthPacket & AddFriendAuthPacket::operator =( const AddFriendAuthPacket & rhs )
{
	*((OutPacket *)this) = (OutPacket)rhs;
	type = rhs.getType();
	buddyQQNum = rhs.getBuddyQQ();
	message = rhs.getMessage();
	return *this;
}

int AddFriendAuthPacket::putBody( unsigned char * buf )
{	
	char qq[20];
	sprintf(qq,"%d", buddyQQNum);
	int offset = strlen(qq);
	memcpy(buf, qq, offset);
	buf[offset++] = DIVIDER;
	buf[offset++] = type;
	buf[offset++] = DIVIDER;
	memcpy(buf + offset, message.c_str(), message.length());	
	return offset + message.length();
}

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

AddFriendAuthReplyPacket::AddFriendAuthReplyPacket( unsigned char * buf, int len )
	: InPacket(buf, len)
{
}

AddFriendAuthReplyPacket::AddFriendAuthReplyPacket( const AddFriendAuthReplyPacket & rhs )
	: InPacket(rhs)
{
}

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

const bool AddFriendAuthReplyPacket::isSentOK( ) const
{
	return replyCode == QQ_ADD_FRIEND_AUTH_REPLY_OK;
}

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

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

DeleteFriendPacket::DeleteFriendPacket( )
	: OutPacket(QQ_CMD_DELETE_FRIEND, true),
	buddyQQNum(0)
{
}

DeleteFriendPacket::DeleteFriendPacket( const int id )
	: OutPacket(QQ_CMD_DELETE_FRIEND, true),
	buddyQQNum(id)
{
}

DeleteFriendPacket::DeleteFriendPacket( const DeleteFriendPacket & rhs )
	: OutPacket(rhs)
{
	buddyQQNum = rhs.getBuddyQQ();
}

DeleteFriendPacket & DeleteFriendPacket::operator =( const DeleteFriendPacket & rhs )
{
	*((OutPacket *)this) = (OutPacket)rhs;
	buddyQQNum = rhs.getBuddyQQ();
	return *this;
}

int DeleteFriendPacket::putBody( unsigned char * buf )
{
	if(buddyQQNum==0) return 0;
	char qq[20];
	sprintf(qq,"%d", buddyQQNum);
	memcpy(buf, qq, strlen(qq));
	return strlen(qq);
}

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

DeleteFriendReplyPacket::DeleteFriendReplyPacket( unsigned char * buf, int len )
	: InPacket(buf, len)
{
}

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

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

const bool DeleteFriendReplyPacket::isDeleted( ) const
{
	return replyCode == QQ_DELETE_FRIEND_REPLY_OK;
}

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

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


DeleteMePacket::DeleteMePacket( )
	: OutPacket(QQ_CMD_DELETE_ME, true),
	buddyQQNum(0)
{
}

DeleteMePacket::DeleteMePacket( const int id )
	: OutPacket(QQ_CMD_DELETE_ME, true),
	buddyQQNum(id)
{
}

DeleteMePacket::DeleteMePacket( const DeleteMePacket & rhs )
	: OutPacket(rhs)
{
	buddyQQNum = rhs.getBuddyQQ();
}

DeleteMePacket & DeleteMePacket::operator =( const DeleteMePacket & rhs )
{
	*((OutPacket *)this) = (OutPacket)rhs;
	buddyQQNum = rhs.getBuddyQQ();
	return *this;
}

int DeleteMePacket::putBody( unsigned char * buf )
{
	if(buddyQQNum==0) return 0;
	int qq = htonl(buddyQQNum);
	memcpy(buf, &qq, 4);
	return 4;
}


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

DeleteMeReplyPacket::DeleteMeReplyPacket( unsigned char * buf, int len )
	: InPacket(buf, len)
{
}

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

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

const bool DeleteMeReplyPacket::isDeleted( ) const
{
	return replyCode == QQ_DELETE_ME_REPLY_OK;
}

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


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

SystemNotificationPacket::SystemNotificationPacket( unsigned char * buf, int len )
	: InPacket(buf, len)
{
}

SystemNotificationPacket::SystemNotificationPacket( const SystemNotificationPacket & rhs )
	: InPacket(rhs)
{
	type = rhs.getType();
	myQQ = rhs.getMyQQ();
	fromQQ = rhs.getFromQQ();
	message = rhs.getMessage();
}

SystemNotificationPacket & SystemNotificationPacket::operator =( const SystemNotificationPacket & rhs )
{
	*((InPacket *)this) = (InPacket)rhs;
	type = rhs.getType();
	myQQ = rhs.getMyQQ();
	fromQQ = rhs.getFromQQ();
	message = rhs.getMessage();
	return *this;	
}

void SystemNotificationPacket::parseBody( )
{
	int start=0 , offset=0;
#ifdef WIN32
	char* buf; buf=(char*)_alloca(bodyLength);
#else
	char buf[bodyLength];
#endif
	
	while(decryptedBuf[offset]!=DIVIDER) offset++;	
	memcpy(buf, decryptedBuf + start, offset-start);		
	buf[offset-start]=0x00;
	start = ++offset;
	type = (uint8_t)atoi(buf);		
	
	
	while(decryptedBuf[offset]!=DIVIDER) offset++;	
	memcpy(buf, decryptedBuf +start, offset-start);		
	buf[offset-start]=0x00;
	start = ++offset;
	fromQQ = atoi(buf);
	
	
	while(decryptedBuf[offset]!=DIVIDER) offset++;	
	memcpy(buf, decryptedBuf+start, offset-start);
	buf[offset-start]=0x00;
	start = ++offset;
	myQQ = atoi(buf);
	
	
	if(offset < bodyLength ) {	
		memcpy(buf, decryptedBuf +start, bodyLength-start);
		buf[bodyLength - start] = 0x00;
		message = buf;
	}else
		message = "";
}

