/* COMPARE FUNCTIONS */
function compareFlirtogramTime(fgA, fgB){
	return (fgA.msTime < fgB.msTime) ? -1 : (fgA.msTime > fgB.msTime ? 1 : 0);
}
function compareFlirtogramMessage(fgA, fgB){
	var msgA = fgA.msg.toLowerCase();
	var msgB = fgB.msg.toLowerCase();

	return (msgA > msgB) ? 1 : (msgA < msgB ? -1 : 0);
}
function compareFlirtogramInbound(fgA, fgB){
	return (fgA.inbound > fgB.inbound) ? -1 : (fgA.inbound < fgB.inbound ? 1 : 0);
}
function cnvCompareFlirtname(cnvA, cnvB){
	var fnA = cnvA.user.flirtname.toLowerCase();
	var fnB = cnvB.user.flirtname.toLowerCase();	
	return (fnA > fnB) ? 1 : (fnA < fnB ? -1 : 0);
}
/* END COMPARE FUNCTIONS */

/* FLIRTOGRAM AND FLIRTOGRAM LIST */
function Flirtogram(id, userId, inbound, type, read, replied, icon, msTime, readableTime, msg){
	this.id = id;
	this.userId = userId;
	this.inbound = inbound;
	this.type = type;
	this.read = read;
	this.replied = replied;
	this.icon = icon;
	this.msTime = msTime;
	this.readableTime = readableTime;
	this.msg = msg;
	this.temp = false;
}

function FlirtogramList(){
	this.flirtograms = new Array();
}
FlirtogramList.prototype.getFlirtogramById = function(id){
		return isDefined(this.flirtograms['F' + id]) ? this.flirtograms['F' + id] : null;
	}
	
FlirtogramList.prototype.addFlirtogram = function(newFg)
	{
		this.flirtograms['F' + newFg.id] = newFg;
		return newFg;
	}
	
FlirtogramList.prototype.updateFlirtogram = function(newFg)
	{
		var fg = this.getFlirtogramById(newFg.id);
		if(fg != null)
		{
			var p ;
			for (p in newFg)
				fg[p] = newFg[p];
			delete p ;
			p = null ;
			return false; // Updated
		}

		this.addFlirtogram(newFg);
		return true; // Inserted
	}
	
FlirtogramList.prototype.removeFlirtogram = function(id){
		if(isDefined(this.flirtograms['F' + id])){
			delete this.flirtograms['F' + id];
			return true;
		}
		return false;
	}
	
	//thread based stuff
FlirtogramList.prototype.removeThread = function(uid)
	{
		for(var f in this.flirtograms){
			var fg = this.flirtograms[f];
			if(fg.userId == uid){
				this.removeFlirtogram(fg.id);
			}
		}
		return false;
	}

FlirtogramList.prototype.getThreadLength = function(userId){
	var thread = this._getThread(userId) ;
	var n = thread.length ;
	delete thread ;
	thread = null ;
	return n ;
}

FlirtogramList.prototype._getThread = function(userId){
		var thread = new Array();
		var f ;
		for(f in this.flirtograms){
			var fg = this.flirtograms[f];
			if(fg.userId == userId){
				thread[thread.length] = fg;
			}
		}
		delete f ;
		f = null ;
		return thread;
	}
	
FlirtogramList.prototype.getThread = function(userId, sortOn, reverse){
		var thread = this._getThread(userId);
		switch(sortOn){
			case 'message':
				thread.sort(compareFlirtogramMessage);
				break;
			case 'time':
				thread.sort(compareFlirtogramTime);
				break;
			case 'inbound':
				thread.sort(compareFlirtogramInbound);
				break;
			default:
				thread.sort(compareFlirtogramTime);
		}
		if(reverse){
			thread.reverse();
		}
		return thread;
	}
	
FlirtogramList.prototype.getMostRecentFlirtogram = function(userId){
		var fg = null ;
		var thread = this.getThread(userId);
		if (thread.length>0)
		{
			var n = thread.length - 1 ;
			while (n>=0)
			{
				fg = thread[n] ;
				if (fg.id>0)
					break ;
				n -= 1 ;
			}
		}
		delete thread ;
		thread = null ;
		return fg;
	}

var lastTempID = new Date().getTime() ;
	/* for adding temp flirtograms*/	
FlirtogramList.prototype.getTempId = function(){
		return 'tempId' + (lastTempID++);
	}
	
FlirtogramList.prototype.addTempFlirtogram = function(sendToUserId, msgType, icon, msg){
		var fg = this.getMostRecentFlirtogram(sendToUserId);
		var msTime = fg == null ? 1 : fg.msTime + 1;
		var tempId = this.getTempId();
		var tmpId = (fg!=null && tempId == fg.id)? fg.id + 1 : tempId;//Sometimes we're just too fast
		var temp = this.addFlirtogram(new Flirtogram(tmpId, sendToUserId, false, msgType, 0, 0, icon, msTime, "Sending...", msg));
		return temp ;
	}

/* END FLIRTOGRAM AND FLIRTOGRAM LIST */

/* CONVERSATION AND CONVERSATION LIST */
function Conversation(userId, msgCount, unreadCount, msTime, readableTime, lastMsg){
	this.user; //used to obtain additional information e.g. flirtname, nb. this MUST be given a value for sort functions to work
	this.userId = userId; //who the current user is having a conversation with
	this.msgCount = msgCount;
	this.unreadCount = unreadCount;
	this.msTime = msTime;
	this.readableTime = readableTime;
	this.lastMsg = lastMsg;
	this.inbound = readableTime.indexOf("Arrived") == 0;	
}

function ConversationList(userList){
	this.conversations = new Array();
	this.userList = userList; //pass to conversation objects so they can get user info e.g. flirtname
	this.selectedId = null;
	this.lastFilter = null;
	this.lastSort = null;
	this.lastReverse = null;
}	
	//id of conversation is taken as user id passed on construction
ConversationList.prototype.getConversationById = function(id){
		return isDefined(this.conversations['C' + id]) ? this.conversations['C' + id] : null;
	}
	
ConversationList.prototype.addConversation = function(newCnv){
		var cnv = this.getConversationById(newCnv.userId);
		newCnv.user = this.userList.getUserById(newCnv.userId);
		if(cnv != null){
			for (var p in newCnv) {
				cnv[p] = newCnv[p];
			}
			return cnv;
		} else {
			this.conversations['C' + newCnv.userId] = newCnv;
			return newCnv;
		}
	}
	
ConversationList.prototype.removeConversation = function(userId){
		if(isDefined(this.conversations['C' + userId])){
			delete this.conversations['C' + userId];
			return true;
		} else {
			return false;
		}
	}
	
ConversationList.prototype.resetConversations = function(){
		var c ;
		for(c in this.conversations){
			delete this.conversations[c];
			this.conversations[c] = null ;
		}
		delete c ;
		c = null ;
		delete this.conversations ;
		this.conversations = null ;
		this.conversations = new Array();
	}
	
ConversationList.prototype.getConversations = function(filter, sortOn, reverse){
		var tempCnvs = new Array();
		for(var c in this.conversations){
			var cnv = this.conversations[c];
			switch(filter){
				case 'favourites':
					if(cnv.user && cnv.user.favourite){
						tempCnvs[tempCnvs.length] = cnv;
					}
					break;
				case 'unread':
					if(cnv.unreadCount){
						tempCnvs[tempCnvs.length] = cnv;
					}
					break;
				case 'blocked':
					if(cnv.user && cnv.user.block){
						tempCnvs[tempCnvs.length] = cnv;
					}
					break;
				case 'online':
					if(cnv.user && cnv.user.online){
						tempCnvs[tempCnvs.length] = cnv;
					}
					break;	
				default:
					tempCnvs[tempCnvs.length] = cnv;
					break;
			}
		}
		
		switch(sortOn){
			case 'flirtname':
				tempCnvs.sort(cnvCompareFlirtname);
				break;
			case 'time':
				tempCnvs.sort(compareFlirtogramTime);
				break;
			default:
				tempCnvs.sort(compareFlirtogramTime);
		}
		if(reverse){
			tempCnvs.reverse();
		}
		
		this.lastFilter = filter;
		this.lastSort = sortOn;
		this.lastReverse = reverse;
	
		return tempCnvs;	
	}
	
ConversationList.prototype.getMostRecentConversation = function(){
		if(this.isEmpty()){
			return null;
		} else {
			var cnvs = this.getConversations();
			for(var p in cnvs){
				return cnvs[p];
			}
		}
	}
	
ConversationList.prototype.isEmpty = function(){
		isArrayEmpty(this.conversations);
	}

/* END CONVERSATION AND CONVERSATION LIST */

/* USER AND USER LIST */
function User(userId, flirtname, gender, mood, photoSrc, ffIconId, age, online, canChat, ageVerified, chatupLine, favourite, block)
{
	//constructor filled in values
	this.id = userId
	this.flirtname = flirtname;
	this.gender = gender ? gender : 'FEMALE';
	this.genderLetter = gender ? gender.charAt(0) : 'F';
	this.mood = mood == '' ? 'SINNER' : mood;
	this.photoSrc = photoSrc;
	this.photoImgSrc = photoSrc?myUnescape(photoSrc):('http://'+stateWindow.staticHost()+'/images/profile/flirtfacegeneric_'+(this.genderLetter=='M'?'man':'wom')+'.gif') ;
	this.ffIconId = ffIconId;
	this.age = age;
	this.online = online;
	this.canChat = canChat;
	this.ageVerified = ageVerified;
	this.chatupLine = chatupLine;
	this.favourite = favourite;
	this.block = block;

	//extra fields for box profile stuff (assigned in boxprofile constructor)
	this.target_mood ;
	this.target_gender ;
	this.chatup_line ;
	
	//even more fields for uberprofile (assigned in uberprofile constructor)
	this.ageRefRange; //array
	this.lastLogin; //string
	this.bodyType;	//integer
	this.description; //more about me...
	this.eyeColour; //integer
	this.flirting; 	//integer
	this.hairColour; //integer
	this.interests; //array
	this.status; 	//integer;
	this.starsign; //integer
	this.position; //integer
	this.rating; 	//integer
	this.dobMysql; //mysql date string
	this.postcode; //string
	this.desiresProximity; //integer
	this.ratedBy; 	//float
	this.snogged;	// integer
	this.snogged_today;	// integer
	this.super_snogs;	// integer
	this.snog_bank;	// integer
	this.private_flirtlink;	// integer
	this.photo_count; // integer
	this.video_count; // integer
	this.gifts;
	this.points;
	this.accessories;	// Array of gift IDs [the index] and counts [the value] - eg accessories[3] = 4 indicates we own 4 gift 3's
	
	//stuff beyond uberprofile
	this.photos;
}
	
//methods
User.prototype.faceIconURL = function() {
	if (this.ffIconId && stateWindow.gift[this.ffIconId])
		return stateWindow.gift[this.ffIconId].faceImageUrl2() ; 
	return 'http://' + stateWindow.staticHost() + '/images/spacer.gif' ;
}

User.prototype.toggleFavourite = function(type){
		var strType = type == 1 ? "make them a favourite" : (type==2?"invite them backstage":"be alerted when they come online");
		if (this.block&1)
		{
			alert("You've blocked "+this.flirtname+". Unblock them if you want to " + strType) ; 
			return ;
		}
		if (this.block&2)
		{
			alert("You've been blocked by "+this.flirtname+". You can't " + strType + " until they forgive you!") ; 
			return ;
		}
		
		var remove = this.favourite & type;
		if(!remove && type == 2 && !stateWindow.iHavePrivateContent){
			alert("You cannot invite someone backstage if you don't have anything private to show them. You can make photos and videos private in 'My Stuff'.");
			return;
		}
		
		if(remove)
			this.favourite = this.favourite & ~type;
		else
			this.favourite = this.favourite | type;

		stateWindow.cascadeUserChange(this, {favourite:'favourite'});
		changeFavouriteOnServer(!remove, this.id, type) ;
	}
	
User.prototype.toggleBlock = function(){
	if (this.block&2)
	{
		alert("You've been blocked already!") ;
		return ;
	}
	this.block = this.block^1 ;
	var changes = new Array() ;
	changes['block'] = 'block' ;
	if (this.favourite>0 && this.block>0)
	{
		changes['favourite'] = 'favourite' ;
		this.favourite = 0 ;
	}
	stateWindow.cascadeUserChange(this, changes);
	changeBlockOnServer(this.block&1, this.id) ;
}

User.prototype.updateSupersnogsSent = function(){
	this.snogged_today++;
	if(this.super_snogs - this.snogged_today < 0){
		this.snog_bank--;
		if(this.snog_bank < 0)this.snog_bank = 0;
	}
	
	stateWindow.cascadeUserChange(this, {snogged_today: "snogged_today"});
	return true; //no update
}

User.prototype.updateSupersnogsReceived = function(){
	this.snogged++;
	stateWindow.cascadeUserChange(this, {snogged: "snogged"});
	return true;
}

User.prototype.updateGiftsReceived = function(){
	this.gifts++;
	stateWindow.cascadeUserChange(this, {gifts: "gifts"});
	return true;
}

User.prototype.getLocationMarkup = function()
{
		var heading = "" ;
		if (this.id==stateWindow.meMyself.id)
		{
				heading += "<a href='basicinfo.jsp?ghost="+stateWindow.getSession()+"&tab=editprofile'>Change my location ("+this.location+")</a>" ;
		}
		else
		{
			if (this.location=='?')
			{
				heading += "<a href='#' onclick='stateWindow.locationSubscription()'>Where am I?</a>" ;
			}
			else
			{
				if (this.location)
					heading += this.location ;
				if (this.distance)
					heading += " ("+this.distance+")" ;
				if (this.country)
					heading += "&nbsp;<img style='vertical-align:bottom' src='http://"+stateWindow.staticHost()+"/../common/flags/"+this.country+".gif'>";
			}
		}
		return heading ;
}

function UserList(){
	this.users = new Array();
}
	
UserList.prototype.getUserById = function(id){
		return isDefined(this.users['U' + id]) ? this.users['U' + id] : null;
	}
	
UserList.prototype.addUser = function(newUser){
		var user = this.getUserById(newUser.id);
		if(user != null){
			for (var p in newUser) {
      			user[p] = newUser[p];
    		}
			return user;
		} else {
			this.users['U' + newUser.id] = newUser;
			return newUser;
		}
	}
UserList.prototype.isUserOnline = function(id){
		var user = this.getUserById(id);
		return user == null ? false : user.online;
	}
UserList.prototype.isEmpty = function(){
		isArrayEmpty(this.users);
	}

/* END USER AND USER LIST */

/* CREATE USER WITH ALL FIELDS, USED BY UBER PROFILE -  SHOULD PROBABLY BE A USER CONSTRUCTOR BUT NEED TO TEST LATER */
function createUser(uid, flirtname, gender, mood, current_photo_id, face_icon_id, age, online, can_chat, age_verified, chatup_line, favourite, block, 
target_mood, target_gender, 
ageRef1, ageRef2, ageRef3, ageRef4, ageRef5, lastLogin, bodyType, description, eyeColour, flirting, hairColour, interest1, interest2, interest3, status, starsign, position, rating, dob_mysql, postcode, ratedBy,
snogged,snogged_today,super_snogs,snog_bank,private_flirtlink,photo_count,video_count,gifts,points,accessories,
distance,location,country)
{
	var u = new User(uid, flirtname, gender, mood, current_photo_id, face_icon_id, age, online, can_chat, age_verified, myUnescape(chatup_line), favourite, block);
	u.target_mood = target_mood != undefined ? (target_mood == '' ? 'SINNER' : target_mood) : undefined;
	u.target_gender = target_gender;
	u.ageRefRange = ageRef1 != undefined ? new Array(ageRef1, ageRef2, ageRef3, ageRef4, ageRef5) : undefined;
	u.lastLogin = lastLogin;
	u.bodyType = bodyType;
	u.description = description != undefined ? myUnescape(description) : undefined;
	u.eyeColour = eyeColour;
	u.flirting = flirting;
	u.hairColour = hairColour;
	u.interests = interest1 != undefined ? new Array(myUnescape(interest1), myUnescape(interest2), myUnescape(interest3)) : undefined;
	u.status = status;
	u.starsign = starsign;
	u.position = position;
	u.rating = rating;
//	u.rating = u.rating ? (u.rating > 10 ? 10.0 : Math.round(10*u.rating)/10) : u.rating;
	u.dobMysql = dob_mysql;
	u.postcode = postcode;
	u.ratedBy = ratedBy;
	u.snogged = snogged;	// integer
	u.snogged_today = snogged_today;	// integer
	u.super_snogs = super_snogs;	// integer
	u.snog_bank = snog_bank;	// integer
	u.private_flirtlink = private_flirtlink;	// integer
	u.photo_count = photo_count ;	// integer
	u.video_count =  video_count ;	// integer
	u.gifts = gifts ;
	u.points = points ;
	u.accessories = accessories ;
	u.distance = distance ;
	u.location = myUnescape(location) ;
	u.country = country;
	stateWindow.updateAndCascadeUser(u) ;
	return u;	
}

//copy user u1 to u2
function copyUser(u1, u2){
	for(var p in u1){
		u2[p] = u1[p];
	}
	//copy internal objects so no refs
	u2.interests = new Array();
	for(i = 0; i < u1.interests.length; i++){
		u2.interests[i] = u1.interests[i];
	}
}
//FUNCTION WRAPPERS TO CREATE OBJECT COS IE AND SAFARI DON'T LIKE USING new hWin.Object() AS A CONSTRUCTION METHOD
function createFlirtogramList(){
	return new FlirtogramList();
}
