/**
 * 
 * 
 * ---------------------------------------------------------------------------
 * 
 * Copyright (C) 2009 Omnium Research Group
 * 
 * ---------------------------------------------------------------------------
 * 
 * LICENSE:
 * 
 * This file is part of Omnium(R) Software.
 * 
 * Omnium(R) Software 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.
 * 
 * Omnium(R) Software 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 Omnium(R) Software; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * ---------------------------------------------------------------------------
 * 
 * @author    Sam Bauers <sam@omnium.net.au>
 * @copyright 2009 Omnium Research Group
 * @license   http://www.gnu.org/licenses/gpl.txt GNU GPL v2
 * @link      http://open.omnium.net.au Omnium Open
 **/



// Make the cronJob variable
var cronJob = false;


// Make the cronChecksum array
var cronChecksum = new Array();

cronChecksum['logout'] = new Array();
cronChecksum['logout']['warned'] = false;
cronChecksum['logout']['done'] = false;

cronChecksum['widgetTime'] = new Array();

cronChecksum['widgetChat'] = new Array();
cronChecksum['widgetChat']['list'] = false;

cronChecksum['widgetUsers'] = new Array();
cronChecksum['widgetUsers']['list'] = false;
cronChecksum['widgetUsers']['visitorCount'] = false;

cronChecksum['widgetChatusers'] = new Array();
cronChecksum['widgetChatusers']['list'] = false;

cronChecksum['widgetChatrooms'] = new Array();
cronChecksum['widgetChatrooms']['list'] = false;


// Sets up the parameters to use in the cron function
function cronParams()
{
	return {
		'user': 			omVars.get('user'),
		'widgetTime': 		omVars.get('widgetTime'),
		'widgetTimeOpen': 	omVars.get('widgetTimeOpen'),
		'widgetChat': 		omVars.get('widgetChat'),
		'widgetChatOpen': 	omVars.get('widgetChatOpen'),
		'chatInvite': 		omVars.get('chatInvite'),
		'widgetUsers': 		omVars.get('widgetUsers'),
		'widgetUsersOpen': 	omVars.get('widgetUsersOpen')
	}
}


// Sets up a periodical call to a php script that then returns it's content (as JSON) to cronEvaluate for parsing
function cron()
{
	// Get the relevant parameters to pass
	params = cronParams();
	
	// Stop the old cronJob if it exists
	if (cronJob) {
		cronJob.stop();
	}
	
	// Start a new cronJob with parameters based on screen state
	cronJob = new Ajax.PeriodicalUpdater(
		omCronDiv,
		omVars.get('url') + 'base/cron.ajax.php',
		{
			asynchronous: true,
			frequency: omVars.get('cronFrequency'),
			onSuccess: cronEvaluate,
			parameters: params
		}
	);
}


// Parses the JSON returned from cron and then acts accordingly
function cronEvaluate(t, json)
{
	//alert(json);
	// Check for imminent logout and offer a login renewal
	if (json.logoutWarning && !cronChecksum.logout.warned) {
		cronChecksum.logout.warned = true;
		Alert.fire(omVars.get('alertLogoutWarning'), false, omVars.get('alertLogoutRenew'), false, 'pingLogin();', omVars.get('alertLogoutIgnore'));
	}
	
	// Check for actual logout and offer a login button
	if (json.logoutNow && !cronChecksum.logout.done) {
		cronChecksum.logout.done = true;
		
		// Stop the cron job so that we don't interfere with logins via other windows or browsers
		if (cronJob) {
			cronJob.stop();
		}
		
		// Close any opened widgets.
		if (omVars.get('widgetUsersOpen') || omVars.get('widgetChatOpen') || omVars.get('widgetTimeOpen')) {
			widgetToggle(false, false);
		}
		Alert.fire(omVars.get('alertLogoutLoggedOut'), false, omVars.get('alertLogoutLogin'), false, omVars.get('url') + 'index.php?error=auth&return=' + encodeURIComponent(window.location));
	}
	
	// If the "Chat" widget is activated
	if (omVars.get('widgetChat')) {
		// If the "Chat" widget is open
		if (omVars.get('widgetChatOpen')) {
			// If the checksum of the current chat users has changed then update the list
			if (cronChecksum.widgetChat.list != json.checksumWidgetChatList) {
				// List is updated via seperate AJAX request
				new Ajax.Updater(
					'omChatList',
					omVars.get('url') + 'widgets/chat/chat.updateChatList.ajax.php',
					{asynchronous:true}
				);
			}
			
			// Set current values to latest request
			cronChecksum.widgetChat.list = json.checksumWidgetChatList;
		}
	}
	
	// If the "Users" widget is activated
	if (omVars.get('widgetUsers')) {
		// Update the menu bar message (function exists inline with HTML)
		updateUsersOnlineMenu(json.userCount);
		
		// If the "Users" widget is open
		if (omVars.get('widgetUsersOpen')) {
			// If the checksum of the currently online users has changed then update the list
			if (cronChecksum.widgetUsers.list != json.checksumWidgetUsersList) {
				// List is updated via seperate AJAX request
				new Ajax.Updater(
					'omUserList',
					omVars.get('url') + 'widgets/users/users.updateUserList.ajax.php',
					{
						parameters:'mode=' + omVars.get('widgetUsersSortingMode'),
						asynchronous:true
					}
				);
			}
			
			// If the checksum of the currently online users has changed or the number of visitors has changed then update the statement
			if (cronChecksum.widgetUsers.list != json.checksumWidgetUsersList || cronChecksum.widgetUsers.visitorCount != json.visitorCount) {
				new Ajax.Updater(
					'omUserStatement',
					omVars.get('url') + 'widgets/users/users.updateUserStatement.ajax.php',
					{asynchronous:true}
				);
			}
			
			// Set current values to latest request
			cronChecksum.widgetUsers.list = json.checksumWidgetUsersList;
			cronChecksum.widgetUsers.visitorCount = json.visitorCount;
		}
	}
	
	// If the "Chatusers" widget is activated
	if (omVars.get('widgetChatusers')) {
		// Update the menu bar message (function exists inline with HTML)
		updateChatusersOnlineMenu(json.chatuserCount);
		
		// If the "Users" widget is open
		if (omVars.get('widgetChatusersOpen')) {
			// If the checksum of the currently online users has changed then update the list
			if (cronChecksum.widgetChatusers.list != json.checksumWidgetChatusersList) {
				// List is updated via seperate AJAX request
				new Ajax.Updater(
					'omChatuserList',
					omVars.get('url') + 'widgets/chat/chat.updateChatuserList.ajax.php',
					{
						parameters:'mode=' + omVars.get('widgetUsersSortingMode'),
						asynchronous:true
					}
				);
			}
			
			// Set current values to latest request
			cronChecksum.widgetChatusers.list = json.checksumWidgetChatusersList;
		}
	}
	
	// If the "Chatrooms" widget is activated
	if (omVars.get('widgetChatrooms')) {
		// Update the menu bar message (function exists inline with HTML)
		updateChatroomsOnlineMenu(json.chatuserCount);
		
		// If the "Users" widget is open
		if (omVars.get('widgetChatroomsOpen')) {
			// If the checksum of the currently online users has changed then update the list
			if (cronChecksum.widgetChatrooms.list != json.checksumWidgetChatroomsList) {
				// List is updated via seperate AJAX request
				new Ajax.Updater(
					'omChatroomList',
					omVars.get('url') + 'widgets/chat/chat.updateRoomList.ajax.php',
					{
						parameters:'mode=' + omVars.get('widgetUsersSortingMode'),
						asynchronous:true
					}
				);
			}
			
			// Set current values to latest request
			cronChecksum.widgetChatrooms.list = json.checksumWidgetChatroomsList;
		}
	}
	
	// If the user is available for chat
	if (omVars.get('chatInvite')) {
		
		// If the chat invite state is waiting for target user to accept/decline
		if (json.chatInviteState == '1') {
			// Display an alert saying that the user has an invitation 
			Alert.fire(
				json.chatInviteUser + '<span style="font-weight: normal;"> invites you to chat in ' + json.chatInviteRoom + '</span>',
				'chatalert_logo.png',
				'Enter ' + json.chatInviteRoom,
				'chat_enter.png',
				'chatInvitationHandler(\'accept\', ' + json.chatInviteId + ', ' + json.chatInviteRoomId + ', ' + json.chatInviter + ', ' + json.chatInviteTarget + ')',
				'Decline invitation',
				'chat_reject.png',
				'chatInvitationHandler(\'decline\', ' + json.chatInviteId + ', false, ' + json.chatInviter + ')'
			);
		}
		
		// If the chat invite state is alerting the user the target user's response
		if (json.chatInviteState == '2') {
			// If the invite is not accepted
			if (json.chatInviteAccepted != '0') {
				var acceptButton;
				if (json.chatInviteInRoom) {
					acceptText = false;
					acceptIcon = false;
				} else {
					acceptText = 'Enter ' + json.chatInviteRoom;
					acceptIcon = 'chat_enter.png';
				}
				// Display the alert telling the user accepts the invitation
				Alert.fire(
					json.chatInviteUser + '<span style="font-weight: normal;"> accepts your invitation</span>',
					'chatalert_logo.png',
					acceptText,
					acceptIcon,
					'chatInvitationHandler(\'alerted\', ' + json.chatInviteId + ', ' + json.chatInviteRoomId + ')'
				);
			} else {
				// Display the alert telling the user declines the invitation
				Alert.fire(
					json.chatInviteUser + '<span style="font-weight: normal;"> regrettably declines your invitation</span>',
					'chatalert_logo.png',
					false,
					false,
					'chatInvitationHandler(\'alerted\', ' + json.chatInviteId + ')'
				);
			}
			
		}
		
		// If the chat invite state is waiting to send an accept/decline alert to the target user
		if (json.chatInviteState == '3') {
			
			// Call the function to check the user status
			this.chatCheckStatus(json.chatInviteUser, json.chatInviteTarget, false, false, json.chatInviteId);
			
		}
		
		// If the invite is stale for the inviter
		if (json.chatInviteState == '4') {
			// Set the invite to inactive
			this.chatInvitationHandler('stale', json.chatInviteId);
			// Display an alert saying that the user has an invitation 
			Alert.fire(
				json.chatInviteUser + '<span style="font-weight: normal;"> has not replied to your invitation and it has timed out</span>',
				'chatalert_logo.png',
				false,
				false,
				'chatInvitationHandler(\'inactive\', ' + json.chatInviteId + ')'
			);
		}
		
		// If the invite is cancelled by the inviter
		if (json.chatInviteState == '5') {
			// Set the invite to inactive
			chatInvitationHandler('inactive', json.chatInviteId);
			// Display an alert saying that the invite cancelled the invitation 
			Alert.fire(
				json.chatInviteUser + '<span style="font-weight: normal;"> has cancelled the invitation</span>',
				'chatalert_logo.png'
			);
		}
		
	}
	
}

// Reset the users recent activity time to now
function pingLogin()
{
	new Ajax.Request(
		omVars.get('url') + 'base/ping.ajax.php',
		{
			asynchronous:true,
			onSuccess:function () {
				cronChecksum.logout.warned = false;
			}
		}
	);
}


// Open the chat window
function chatLaunch(room)
{
	if (!room) {
		room = 0;
	}
	
	var chatWin = window.open(
		omVars.get('url') + 'widgets/chat/index.php?room=' + room,
		'chatWindow',
		'width=160, height=160, dependent=yes, directories=no, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, toolbar=no'
	);
}

function chatCheckStatus(userId, targetUserId, inviteAlert, createInvitation, inviteId) {
	params = 'id_users_target=' + targetUserId;
	opt = {
		parameters:params,
		onSuccess: function (t, json) {
			if (json.result) {
				if (inviteAlert) {
					Alert.fire(
						t.responseText,
						'chatalert_logo.png',
						'Invite',
						false,
						'chatCheckStatus(' + userId + ', ' + targetUserId + ', false, true, ' + inviteId + ')',
						'Cancel'
					);
				} else if (createInvitation) {
					this.chatCreateInvitation(userId, targetUserId);
				}
			} else if (json.chatroomId) {
				if (!inviteAlert && !createInvitation) {
					// Call the invitation handler to remove the invitation
					this.chatInvitationHandler('delete', false, false, userId, targetUserId);
				}
				widgetToggle(null, null);
				Alert.fire(
					t.responseText,
					'chatalert_logo.png',
					'Enter chatroom',
					'chat_enter.png',
					'chatLaunch(' + json.chatroomId + ')',
					'Cancel'
				);
			} else {
				if (!inviteAlert) {
					// Call the invitation handler to remove the invitation
					this.chatInvitationHandler('delete', inviteId, false, userId, targetUserId);
				}
				Alert.fire(t.responseText, 'chatalert_logo.png');
			}
		}
	}
	new Ajax.Request(omVars.get('url') + 'widgets/chat/chat.checkStatus.ajax.php', opt);
}

function chatCreateInvitation(userId, targetUserId) {
	// Get the selected chatroom from the dropdown
	selectObj = $('omInvitationSelect');
	chatroomId = selectObj.options[selectObj.options.selectedIndex].value;
	params = 'id_users=' + userId;
	params += '&id_users_target=' + targetUserId;
	params += '&id_chatrooms=' + chatroomId;
	
	new Ajax.Request(
		omVars.get('url') + 'widgets/chat/chat.setInvitation.ajax.php',
		{
			parameters: params,
			onSuccess:function (t) {
				if (t.responseText == 1) {
					widgetToggle(null, null);
				} else {
					Alert.fire('Invitation sending failed');
				}
			}
		}
	);
}

// Deals with accepting or declining with invitations
function chatInvitationHandler(action, inviteId, roomId, userId, targetUserId) {
	new Ajax.Request(
		omVars.get('url') + 'widgets/chat/chat.invitationHandler.ajax.php',
		{
			parameters: {
				'action': 				action,
				'id_chatrooms_invites': inviteId,
				'id_users': 			userId,
				'id_users_target': 		targetUserId
			},
			onSuccess: function(t) {
				if (t.responseText != 1 && t.responseText != 0) {
					Alert.fire(
						t.responseText,
						'chatalert_logo.png',
						false,
						false,
						'chatInvitationHandler(\'inactive\', ' + inviteId + ')'
					);
				}
			}
		}
	);
	
	if (action == 'cancel') {
		widgetToggle(null, null);
	}
	if (roomId) {
		chatLaunch(roomId);
	}
}

// Resize a windows inner height and width
function innerResizeTo(width, height, boom)
{
	var doResize = true;
	
	if (boom) {
		var bx = false;
		var by = false;
		if (window.innerWidth && window.innerHeight) {
			bx = window.innerWidth;
			by = window.innerHeight;
		} else if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientHeight) {
			bx = document.documentElement.clientWidth;
			by = document.documentElement.clientHeight;
		} else if (document.body) {
			bx = document.body.clientWidth;
			by = document.body.clientHeight;
		}
		
		if (bx > 170 && by > 170) {
			doResize = false;
		}
	}
	
	if (doResize) {
		window.resizeTo(width, height);
		var ix = false;
		var iy = false;
		var ex = false;
		var ey = false;
		if (window.innerWidth && window.innerHeight) {
			ix = window.innerWidth;
			iy = window.innerHeight;
			ex = window.outerWidth;
			ey = window.outerHeight;
		} else if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientHeight) {
			ix = document.documentElement.clientWidth;
			iy = document.documentElement.clientHeight;
			ex = width;
			ey = height;
		} else if (document.body) {
			ix = document.body.clientWidth;
			iy = document.body.clientHeight;
			ex = width;
			ey = height;
		}
		
		if (ix && iy && ex && ey) {
			var dx = (ex - ix);
			var dy = (ey - iy);
			var rx = (width + dx);
			var ry = (height + dy);
			window.resizeTo(rx, ry);
		}
	}
}


// Restyles the widget menu on mouse over
function widgetOver(linkObj, widget)
{
	if (widget != omVars.get('openWidget')) {
		linkObj.className = 'menuItem menuItemOver';
		if (omVars.get('pageLoaded')) {
			$('omWidgetMenu' + widget + 'Arrow').src = omVars.get('widgetArrowDir') + 'arrowOver.png';
		}
	}
}


// Restyles the widget menu on mouse out
function widgetOut(linkObj, widget)
{
	if (widget != omVars.get('openWidget')) {
		linkObj.className = 'menuItem';
		if (omVars.get('pageLoaded')) {
			$('omWidgetMenu' + widget + 'Arrow').src = omVars.get('widgetArrowDir') + 'arrowOut.png';
		}
	}
}


// Restyles the widget menu when widget is open
function widgetOn(linkObj, widget)
{
	linkObj.className = 'menuItem menuItemOn';
	$('omWidgetMenu' + widget + 'Arrow').src = omVars.get('widgetArrowDir') + 'arrowOn.png';
}


// Opens and closes widget items and restyles the menu accordingly
function widgetToggle(linkObj, widget)
{
	// If the selected widget is not currently open
	if (widget != omVars.get('openWidget')) {
		// If there is an open widget then close it
		if (omVars.get('openWidget')) {
			$('omWidgetMenu' + omVars.get('openWidget')).className = 'menuItem';
			if (omVars.get('pageLoaded')) {
				$('omWidgetMenu' + omVars.get('openWidget') + 'Arrow').src = omVars.get('widgetArrowDir') + 'arrowOut.png';
			}
			$('omWidgetBody' + omVars.get('openWidget')).hide();
			
			if (!widget) {
				$('omWidgetScreen').hide();
				$('omWidgetBody').hide();
			}
			
			widgetDeInit(omVars.get('openWidget'));
			
			if (!widget && omVars.get('openWidget')) {
				omVars.set('openWidget', false);
			}
		}
		
		// If a widget has been selected then open it
		if (widget) {
			widgetOn(linkObj, widget);
			
			if (!omVars.get('openWidget')) {
				$('omWidgetScreen').show();
				$('omWidgetBody').show();
			}
			$('omWidgetBody' + widget).show();
			
			widgetInit(widget);
			
			omVarsRegister({openWidget:widget});
		}
	} else {
		// Close the selected widget
		omVars.set('openWidget', false);
		widgetOver(linkObj, widget);
		
		if (omVars.get('pageLoaded')) {
			$('omWidgetMenu' + widget + 'Arrow').src = omVars.get('widgetArrowDir') + 'arrowOver.png';
		}
		$('omWidgetScreen').hide();
		$('omWidgetBody' + widget).hide();
		$('omWidgetBody').hide();
		
		widgetDeInit(widget);
	}
	
	// Stops the link that was clicked from being highlighted
	if (linkObj) {
		linkObj.blur();
	}
}


// Gets the latest time for the selected users/zones in the Time widget
function widgetTimeUpdater(input)
{
	if (input) {
		params = 'input=' + input;
	} else {
		params = '';
	}
	
	new Ajax.Request(
		omVars.get('url') + 'widgets/time/time.updater.ajax.php',
		{
			parameters: params,
			onSuccess: widgetTimeResponse
		}
	);
}


// Actually updates the Time widget
function widgetTimeResponse(t, json)
{
	if (json.timeInput) {
		$('omWidgetBodyTimeInput').value = json.timeInput;
	}
	
	$('omWidgetBodyTimeOutputNameLeft').update(json.nameLeft);
	$('omWidgetBodyTimeOutputTimeLeft').update(json.timeLeft);
	$('omWidgetBodyTimeOutputDateLeft').update(json.dateLeft);
	$('omWidgetBodyTimeOutputLocationLeft').update(json.locationLeft);
	
	if (json.flagLeft) {
		$('omWidgetBodyTimeOutputFlagLeft').src = omVars.get('flagDir') + json.flagLeft + '.gif';
	} else {
		$('omWidgetBodyTimeOutputFlagLeft').src = omVars.get('blankSrc');
	}
	
	$('omWidgetBodyTimeOutputZoneLeft').update(json.zoneLeft);
	$('omWidgetBodyTimeOutputTimeRight').update(json.timeRight);
	$('omWidgetBodyTimeOutputDateRight').update(json.dateRight);
	$('omWidgetBodyTimeOutputLocationRight').update(json.locationRight);
	
	if (json.flagRight) {
		$('omWidgetBodyTimeOutputFlagRight').src = omVars.get('flagDir') + json.flagRight + '.gif';
	} else {
		$('omWidgetBodyTimeOutputFlagRight').src = omVars.get('blankSrc');
	}
	
	$('omWidgetBodyTimeOutputZoneRight').update(json.zoneRight);
	$('omWidgetBodyTimeOutputComparison').update(json.comparison);
}


// Initialises selected widget
function widgetInit(widget)
{
	switch (widget) {
		case 'Time':
			// Update the current Times in the widget
			widgetTimeUpdater();
			omVars.set('widgetTimeOpen', 1);
			break;
		case 'Chat':
			omVars.set('widgetChatOpen', 1);
			// Reload cron
			cron();
			break;
		case 'User':
			omVars.set('widgetUsersOpen', 1);
			// Reload cron
			cron();
			break;
	}
}


// De-initialises selected widget
function widgetDeInit(widget)
{
	switch (widget) {
		case 'Time':
			omVars.set('widgetTimeOpen', 0);
			break;
		case 'Chat':
			omVars.set('widgetChatOpen', 0);
			// Reload cron
			cron();
			break;
		case 'User':
			omVars.set('widgetUsersOpen', 0);
			// Reload cron
			cron();
			break;
	}
}


function widgetSetChatStatus(input)
{
	new Ajax.Request(
		omVars.get('url') + 'widgets/chat/chat.setChatStatus.ajax.php',
		{
			parameters: { 'input': input },
			onSuccess: function (t) {
				omVars.set('chatInvite', input);
				
				$('omWidgetChatStatusResult').update(t.responseText);
				
				new Effect.Appear('omWidgetChatStatusResult');
				
				new Effect.Fade('omWidgetChatStatusResult', {delay:2});
				
				cron();
			}
		}
	);
}

function widgetSetUserSortingMode(mode)
{
	omVars.set('widgetUsersSortingMode', mode);
	cronChecksum.widgetUsers.list = 'xxx';
	cron();
}

function updateUsersOnlineMenu(number)
{
	return false;
}
