//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//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.

#include "stdafx.h"
#include "server.h"
#include "opcodes.h"
#include "emule.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


CServer::CServer(ServerMet_Struct* in_data){
	taglist = new CTypedPtrList<CPtrList, CTag*>;
	port = in_data->port;
	tagcount = 0;
	ip = in_data->ip;
	in_addr host;
	host.S_un.S_addr = ip;
	strcpy(ipfull,inet_ntoa(host));
	files = 0;
	users = 0;
	preferences = 0;
	ping = 0;
	description = 0;
	listname = 0;
	dynip = 0;
	failedcount = 0; 
	lastpinged = 0;
	staticservermember=0;
	maxusers=0;
}

CServer::CServer(uint16 in_port, char* i_addr){
	taglist = new CTypedPtrList<CPtrList, CTag*>;
	port = in_port;
	tagcount = 0;
	if (inet_addr(i_addr) == INADDR_NONE){
		dynip = nstrdup(i_addr);
		ip = 0;
	}
	else{
		ip = inet_addr(i_addr);
		dynip = 0;
	}
	in_addr host;
	host.S_un.S_addr = ip;
	strcpy(ipfull,inet_ntoa(host));
	files = 0;
	users = 0;
	preferences = 0;
	ping = 0;
	description = 0;
	listname = 0;
	failedcount = 0; 
	lastpinged = 0;
	staticservermember=0;
	maxusers=0;
}

// copy constructor
CServer::CServer(CServer* pOld)
{
	taglist = new CTypedPtrList<CPtrList, CTag*>;
	for(POSITION pos = pOld->taglist->GetHeadPosition(); pos != NULL; pOld->taglist->GetNext(pos))
	{
		CTag* pOldTag = pOld->taglist->GetAt(pos);
		taglist->AddTail(pOldTag->CloneTag());
	}
	port = pOld->port;
	ip = pOld->ip; 
	staticservermember=pOld->IsStaticMember();
	tagcount = pOld->tagcount;
	strcpy(ipfull,pOld->ipfull);
	files = pOld->files;
	users = pOld->users;
	preferences = pOld->preferences;
	ping = pOld->ping;
	failedcount = pOld->failedcount; 
	lastpinged = pOld->lastpinged;
	maxusers = pOld->maxusers;
	if (pOld->description)
		description = nstrdup(pOld->description);
	else
		description = NULL;
	if (pOld->listname)
		listname = nstrdup(pOld->listname);
	else
		listname = NULL;
	if (pOld->dynip)
		dynip = nstrdup(pOld->dynip);
	else
		dynip = NULL;
}

CServer::~CServer(){
	if (description)
		delete[] description;
	if (listname)
		delete[] listname;
	if (dynip)
		delete[] dynip;
	for(POSITION pos = taglist->GetHeadPosition(); pos != NULL; taglist->GetNext(pos))
		delete taglist->GetAt(pos);
	taglist->RemoveAll();
	delete taglist;
}

bool CServer::AddTagFromFile(CSafeFile* servermet){
	if (servermet == 0)
		return false;
	CTag* tag = new CTag(servermet);
	switch(tag->tag->specialtag){		
					case ST_SERVERNAME:
						if(tag->tag->stringvalue)
							listname = nstrdup(tag->tag->stringvalue);
						else
							listname = NULL;
						delete tag;
						break;
					case ST_DESCRIPTION:
						if( tag->tag->stringvalue )
							description = nstrdup(tag->tag->stringvalue);
						else
							description = NULL;
						delete tag;
						break;
					case ST_PREFERENCE:
						preferences =tag->tag->intvalue;
						delete tag;
						break;
					case ST_PING:
						ping = tag->tag->intvalue;
						delete tag;
						break;
					case ST_DYNIP:
						if ( tag->tag->stringvalue )
							dynip = nstrdup(tag->tag->stringvalue);
						else
							dynip = NULL;
						delete tag;
						break;
					case ST_FAIL:
						failedcount = tag->tag->intvalue;
						delete tag;
						break;
					case ST_LASTPING:
						lastpinged = tag->tag->intvalue;
						delete tag;
						break;
					case ST_MAXUSERS:
						maxusers = tag->tag->intvalue;
						delete tag;
						break;
					default:
						if (tag->tag->specialtag){
							tag->tag->tagname = nstrdup("Unknown");
							AddTag(tag);
						}
						else if (!strcmp(tag->tag->tagname,"files")){
							files = tag->tag->intvalue;
							delete tag;
						}
						else if (!strcmp(tag->tag->tagname,"users")){
							users = tag->tag->intvalue;
							delete tag;
						}
						else
							AddTag(tag);
	}
	return true;
}

void CServer::SetListName(char* newname){
	if (listname)
		delete[] listname;
	if (newname)
		listname = nstrdup(newname);
	else
		listname = NULL;
}

void CServer::SetDescription(char* newname){
	if (description)
		delete[] description;
	if( newname )
		description = nstrdup(newname);
	else
		description = NULL;
}

void CServer::FillWindowTags(CTreeCtrl* wnd,HTREEITEM rootitem){
	POSITION pos;
	char buffer[255];
	if (description) {
		sprintf(buffer,GetResString(IDS_DESC),description);
		wnd->InsertItem(buffer,-1,-1,rootitem);
	}
	sprintf(buffer,GetResString(IDS_IP)+": %s",ipfull);
	wnd->InsertItem(buffer,-1,-1,rootitem);
	sprintf(buffer,GetResString(IDS_PORT)+": %i",port);
	wnd->InsertItem(buffer,-1,-1,rootitem);
	if (ping) {
		sprintf(buffer,GetResString(IDS_PING)+": %i",ping);
		wnd->InsertItem(buffer,-1,-1,rootitem);
	}
	if (users) {
		sprintf(buffer,GetResString(IDS_USERS),users);
		wnd->InsertItem(buffer,-1,-1,rootitem);
	}
	if (files) {
		sprintf(buffer,GetResString(IDS_FILES)+": %i",files);
		wnd->InsertItem(buffer,-1,-1,rootitem);
	}
	CTag* cur_tag;
	for(int i = 0; i != taglist->GetCount();i++) {
		pos = taglist->FindIndex(i);
		cur_tag = taglist->GetAt(pos);
		if (cur_tag->tag->specialtag)
			continue;
		if (cur_tag->tag->type == 2)
			sprintf(buffer,"%s: %s",cur_tag->tag->tagname,cur_tag->tag->stringvalue);
		else if (cur_tag->tag->type == 3)
			sprintf(buffer,"%s: %i",cur_tag->tag->tagname,cur_tag->tag->intvalue);
		else
			continue;
		wnd->InsertItem(buffer,-1,-1,rootitem);
   }
}

char* CServer::GetAddress(){
	if (dynip)
		return dynip;
	else
		return ipfull;
}

void CServer::SetID(uint32 newip){
	ip = newip;
	in_addr host;
	host.S_un.S_addr = ip;
	strcpy(ipfull,inet_ntoa(host));
}

void CServer::SetDynIP(char* newdynip){
	if (dynip)
		delete[] dynip;
	if( newdynip )
		dynip = nstrdup(newdynip);
	else
		dynip = NULL;
}
