/*
 * Copyright 2005 - 2009  Zarafa B.V.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3, 
 * as published by the Free Software Foundation with the following additional 
 * term according to sec. 7:
 *  
 * According to sec. 7 of the GNU Affero General Public License, version
 * 3, the terms of the AGPL are supplemented with the following terms:
 * 
 * "Zarafa" is a registered trademark of Zarafa B.V. The licensing of
 * the Program under the AGPL does not imply a trademark license.
 * Therefore any rights, title and interest in our trademarks remain
 * entirely with us.
 * 
 * However, if you propagate an unmodified version of the Program you are
 * allowed to use the term "Zarafa" to indicate that you distribute the
 * Program. Furthermore you may use our trademarks where it is necessary
 * to indicate the intended purpose of a product or service provided you
 * use it in accordance with honest practices in industrial or commercial
 * matters.  If you want to propagate modified versions of the Program
 * under the name "Zarafa" or "Zarafa Server", you may only do so if you
 * have a written permission by Zarafa B.V. (to acquire a permission
 * please contact Zarafa at trademark@zarafa.com).
 * 
 * The interactive user interface of the software displays an attribution
 * notice containing the term "Zarafa" and/or the logo of Zarafa.
 * Interactive user interfaces of unmodified and modified versions must
 * display Appropriate Legal Notices according to sec. 5 of the GNU
 * Affero General Public License, version 3, when you propagate
 * unmodified or modified versions of the Program. In accordance with
 * sec. 7 b) of the GNU Affero General Public License, version 3, these
 * Appropriate Legal Notices must retain the logo of Zarafa or display
 * the words "Initial Development by Zarafa" if the display of the logo
 * is not reasonably feasible for technical reasons."
 * 
 * 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 Affero General Public License for more details.
 *  
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

appointmentitemmodule.prototype = new ItemModule;
appointmentitemmodule.prototype.constructor = appointmentitemmodule;
appointmentitemmodule.superclass = ItemModule.prototype;

function appointmentitemmodule(id)
{
	if(arguments.length > 0) {
		this.init(id);
	}

	// The element ID's of recurrence information
	this.recurids = new Array('recurring', 'startocc', 'endocc', 'start', 'end', 'term', 'regen', 'everyn', 'subtype', 'type', 'weekdays', 'month', 'monthday', 'nday', 'numoccur');
}

appointmentitemmodule.prototype.init = function(id)
{
	appointmentitemmodule.superclass.init.call(this, id);
}

appointmentitemmodule.prototype.executeOnLoad = function()
{
	initAppointment();
	showRecurrence();
	
	var meeting = this.itemProps.meeting;
	
	//Show tracking tab if it meeting Appointment.
	if (meeting == 1){
		var tab_tracking = dhtml.getElementById("tab_tracking");
		if (tab_tracking) {
			if (webclient.userEntryid == this.itemProps.sent_representing_entryid){
				dhtml.removeClassName(tab_tracking, "tab_hide");
			} else {
				dhtml.addClassName(tab_tracking, "tab_hide");
			}
		}
	}
}

appointmentitemmodule.prototype.setStartTime = function(unixtime)
{
	dhtml.getElementById("startdate").setAttribute("unixtime",unixtime);
	dhtml.getElementById("commonstart").setAttribute("unixtime",unixtime);
	appoint_dtp.setStartValue(unixtime);
}

appointmentitemmodule.prototype.setEndTime = function(unixtime)
{
	dhtml.getElementById("duedate").setAttribute("unixtime",unixtime);
	dhtml.getElementById("commonend").setAttribute("unixtime",unixtime);
	appoint_dtp.setEndValue(unixtime);
}

appointmentitemmodule.prototype.getStartTime = function()
{
	return appoint_dtp.getStartValue();
}

appointmentitemmodule.prototype.getEndTime = function()
{
	return appoint_dtp.getEndValue();
}

/**
 * Function will return the selected users
 * @return Array[]->entryid
 *                ->fullname
 *                ->emailaddress
 */ 
appointmentitemmodule.prototype.getUserList = function()
{
	var result = new Array();
	var index = 0;
	result[index] = this.owner;
	index++;

	var userList = dhtml.getElementById("to").value.split(";");
	var organizerFound = false;
	if(dhtml.getElementById("to").value.length > 0){
		for(user in userList){
			if(userList[user].trim().length == 0)
				continue;

			result[index] = new Object();
			result[index]["recipienttype"] = 1;
			result[index]["recipient_flags"] = 1;	//recipient flag for attendees.

			userList[user] = userList[user].trim();

			var posLeft = userList[user].indexOf("<");
			var posRight = userList[user].indexOf(">");
			if(posLeft > 0 && posRight > 0){
				//take the email address and fullname
				result[index]["fullname"] = userList[user].substring(0,posLeft).trim();
				result[index]["emailaddress"] = userList[user].substring(posLeft+1,posRight).trim();
				// Check if the sent_representing_email_address is set, since this is not the case in a new appointment
				if(this.itemProps.sent_representing_email_address){
					if(result[index]["emailaddress"].toLowerCase() == this.itemProps.sent_representing_email_address.toLowerCase()){
						result[index]["recipienttype"] = 0;
						result[index]["recipient_flags"] = 3;	//recipient flag for meeting organizer
					}
				}
			}
			else{
				if(userList[user].length > 0){
					result[index]["fullname"] = userList[user];
				}
			}
			index++;
		}
	}

	var userList = dhtml.getElementById("cc").value.split(";");
	if(dhtml.getElementById("cc").value.length > 0){
		for(user in userList){
			if(userList[user].trim().length == 0)
				continue;
				
			result[index] = new Object();
			result[index]["recipienttype"] = 2;
			result[index]["recipient_flags"] = 1;

			userList[user] = userList[user].trim();

			var posLeft = userList[user].indexOf("<");
			var posRight = userList[user].indexOf(">");
			if(posLeft > 0 && posRight > 0){
				//take the email address and fullname
				result[index]["fullname"] = userList[user].substring(0,posLeft).trim();
				result[index]["emailaddress"] = userList[user].substring(posLeft+1,posRight).trim();
			}
			else{
				if(userList[user].length > 0){
					result[index]["fullname"] = userList[user];
				}
			}
			index++;
		}
	}

	var userList = dhtml.getElementById("bcc").value.split(";");
	if(dhtml.getElementById("bcc").value.length > 0){
		for(user in userList){
			if(userList[user].trim().length == 0)
				continue;
				
			result[index] = new Object();
			result[index]["recipienttype"] = 3;

			userList[user] = userList[user].trim();

			var posLeft = userList[user].indexOf("<");
			var posRight = userList[user].indexOf(">");
			if(posLeft > 0 && posRight > 0){
				//take the email address and fullname
				result[index]["fullname"] = userList[user].substring(0,posLeft).trim();
				result[index]["emailaddress"] = userList[user].substring(posLeft+1,posRight).trim();
			}
			else{
				if(userList[user].length > 0){
					result[index]["fullname"] = userList[user];
				}
			}
			index++;
		}
	}

	return result;
}

/**
 * Function will create the users in this given list
 * @param  Object[]->entryid
 *                 ->fullname
 *                 ->emailaddress 
 */ 
appointmentitemmodule.prototype.setUserList = function(inputUserlist)
{
	var result = "";
	var resultTO = "";
	var resultCC = "";
	var resultBCC = "";
	for(user in inputUserlist){
		var userData = inputUserlist[user];
		if(userData["recipient_flags"] == 3){
			if(!this.owner){
				this.owner = userData;
			}
		}else{
			/**
			 * If e-mail address is an external e-mail address.
			 * Conditions for external e-mail address
			 * 1) If entryid is not there for userdata.
			 * 2) If fullname and emailaddress are same.
			 * 3) If fullname and entryid are same. 
			 * (When userdata is set from freebusy module then 
			 * at that time entryid for external email address contains external e-mail address.)
			 */
			if(userData["entryid"].length == 0 || (userData["fullname"] == userData["emailaddress"]) || (userData["fullname"] == userData["entryid"])){
				switch(userData["recipienttype"]){
					case 2:
						resultCC += userData["fullname"]+"; ";
						break;
					case 3:
						resultBCC += userData["fullname"]+"; ";
						break;
					case 0:
						var emailaddress = this.itemProps["sent_representing_email_address"] || userData["emailaddress"];
						resultTO += userData["fullname"]+" <"+emailaddress+">; ";
						break;
					default:
						resultTO += userData["fullname"]+"; ";
						break;
				}
				result += userData["fullname"]+"; ";
			}
			else{
				switch(userData["recipienttype"]){
					case 2:
						resultCC += userData["fullname"]+" <"+userData["emailaddress"]+">; ";
						break;
					case 3:
						resultBCC += userData["fullname"]+" <"+userData["emailaddress"]+">; ";
						break;
					case 0:
						var emailaddress = this.itemProps["sent_representing_email_address"] || userData["emailaddress"];
						resultTO += userData["fullname"]+" <"+emailaddress+">; ";
						break;
					default:
						resultTO += userData["fullname"]+" <"+userData["emailaddress"]+">; ";
						break;
				}
				result += userData["fullname"]+" <"+userData["emailaddress"]+">; ";
			}
		}
	}
	dhtml.getElementById("toccbcc").value = result;
	dhtml.getElementById("to").value = resultTO;
	dhtml.getElementById("cc").value = resultCC;
	dhtml.getElementById("bcc").value = resultBCC;
	this.oldToValue = result;
}


appointmentitemmodule.prototype.getRecurrence = function()
{
	var recurrence = new Object;

	for(i=0;i < this.recurids.length; i++) {		
		recurrence[this.recurids[i]] = parseInt(dhtml.getElementById(this.recurids[i]).value);
	}
	
	//Set allday_event flag to show it in recurrence dialog
	if (parseInt(dhtml.getElementById("endocc").value, 10) == 1440){
		recurrence["allday_event"] = 1;
	}
	
	return recurrence;
}

appointmentitemmodule.prototype.setRecurrence = function(recurrence)
{
	if(recurrence) {

		for(i=0;i < this.recurids.length; i++) {
			dhtml.getElementById(this.recurids[i]).value = recurrence[this.recurids[i]];		
		}
	
		dhtml.getElementById('recurring').value = 1;
		dhtml.getElementById('recurring_reset').value = 1;
		dhtml.getElementById('icon_index').value = 1025;
		
		//Set appointment as alldayevent
		if (recurrence["alldayevent"] && recurrence["alldayevent"] == 1) {
			//Set startdate and enddate
			dhtml.setValue(dhtml.getElementById("checkbox_alldayevent"), true);
			onChangeAllDayEvent();
			dhtml.getElementById("endocc").value = 1440;
			dhtml.getElementById("duration").value = 1440;
		}
	} else {
		dhtml.getElementById('recurring').value = 0;
		dhtml.getElementById('icon_index').value = 1024;
		dhtml.getElementById('recurtext').innerHTML = "";
	}

	showRecurrence();
}

appointmentitemmodule.prototype.setTimezone = function(tz)
{
	var elems = new Array('timezone','timezonedst','dststartmonth', 'dststartweek', 'dststartday', 'dststarthour',
							'dstendmonth','dstendweek', 'dstendday', 'dstendhour');
	if(tz) {
		for(var i=0; i< elems.length; i++) {
			dhtml.getElementById(elems[i]).value = tz[elems[i]];
		}
	}
}

// If send is true, send a cancellation
appointmentitemmodule.prototype.deleteMessage = function (send,basedate)
{
	if(basedate) {
		var req = new Object;
		req['store'] = this.storeid;
		req['parententryid'] = this.parententryid;
		req['entryid'] = this.messageentryid;
		req['delete'] = 1;
		req['props'] = new Object;
		req['props']['entryid'] = this.messageentryid;
		req['props']['basedate'] = parseInt(basedate, 10);
		parentWebclient.xmlrequest.addData(this, 'save', req, webclient.modulePrefix);
	} else {
		if(send) {
			var req = new Object;
			req['store'] = this.storeid;
			req['entryid'] = this.messageentryid;
			// Cancel automatically deletes the item
			parentWebclient.xmlrequest.addData(this, 'cancelInvitation', req, webclient.modulePrefix);
		} else {
			appointmentitemmodule.superclass.deleteMessage.call(this);	
		}
	}
}

appointmentitemmodule.prototype.saveMessage = function (props, send, recipients, dialog_attachments)
{
	appointmentitemmodule.superclass.saveMessage.call(this, props, send, recipients, dialog_attachments);
}

appointmentitemmodule.prototype.execute = function (type, action)
{
	switch(type)
	{
		case "item":
			this.item(action);
			webclient.menu.showMenu();
			break;
		case "saved":
			this.messageSaved(action);
			break;
	}
}


/**
 * Function which saves an item.
 * @param object props the properties to be saved
 * @param string dialog_attachments used to add attachments (optional)   
 */ 
appointmentitemmodule.prototype.save = function(props, send, recipients, dialog_attachments)
{
	var data = new Object();
	if(this.storeid) {
		data["store"] = this.storeid;
	}

	if(this.isMeeting == true && props["entryid"] == ""){
		// Add human readable BODY Text.
		props["body"] = _("When") + ": " +  
						strftime(_("%A, %B %e, %Y %H:%M"), props['startdate']) + " - " +
						strftime(_("%A, %B %e, %Y %H:%M"), props['duedate']) + "\n" +  
						_("Where") + ": "  + props['location'] + "\n\n" + 
						"*~*~*~*~*~*~*~*~*~*\n\n" + props["body"];
	}

	if(this.parententryid)
		data["parententryid"] = this.parententryid;
		
	data["props"] = props;
	if (recipients){
		data["recipients"] = recipients;
		if(this.owner){
			data["recipients"]["recipient"].unshift({
				"address": this.owner["email_address"],
				"name": this.owner["fullname"],
				"type": "mapi_to"
			});
		}
	}

	if (dialog_attachments)
		data["dialog_attachments"] = dialog_attachments;
	
	if(this.message_action) {
		data["message_action"] = new Object();
		data["message_action"]["action_type"] = this.message_action;
		data["message_action"]["entryid"] = this.message_action_entryid;
	}
	
	if(send) {
		data["send"] = true;
	}

	//webclient.xmlrequest.addData(this, "save", data);
	//webclient.xmlrequest.sendRequest();
//TODO: update main webclient??
	if(typeof(parentWebclient) != "undefined") {
		parentWebclient.xmlrequest.addData(this, "save", data, webclient.modulePrefix);
		/**
		 * We dont want to wait while saving the message,
		 * b,couz if we are also sending response to meeting request
		 * then saving should be done prior to sending response.
		 */
		parentWebclient.xmlrequest.sendRequest(false);
//TODO: remove BETA quick fix
	}else{
		webclient.xmlrequest.addData(this, "save", data); 
		webclient.xmlrequest.sendRequest();
	}
}


appointmentitemmodule.prototype.messageSaved = function(action)
{
	if(Number(dhtml.getXMLValue(action, "meeting_request_saved"))){
		if(Number(dhtml.getXMLValue(action, "sent_meetingrequest"))){
			// Check if resources are planned in this appointment
			var userlist = this.getUserList();
			var resourcesPlanned = false;
			for(var i=0;i<userlist.length;i++){
				if(userlist[i]["recipienttype"] == 3){
					resourcesPlanned = true;
					break;
				}
			}
			if(resourcesPlanned){
				alert(_("Resources have been planned."));
			}
		}
		/**
		 * Dont close window, untill changes in meeting
		 * request are saved and response is send,
		 * while accepting/tentatively meeting request.
		 */
		if (!module.savingMeetingRequest) {
			window.close();
		}
	}else if(Number(dhtml.getXMLValue(action, "errorcode"))){
		var name = (dhtml.getXMLValue(action, "displayname"))?dhtml.getXMLValue(action, "displayname"):'(Unknown)';
		/**
		 * Error codes:
		 * 1: No access/permissions.
		 * 2: Resource does not automatically accept meeting requests (disabled atm, mail is sent instead).
		 * 3: Resource declines recurring meeting requests.
		 * 4: Resource declines conflicting meeting requests.
		 */
		switch(Number(dhtml.getXMLValue(action, "errorcode"))){
			case 1:
				alert(_("You marked \"%s\" as a resource. You cannot schedule a meeting with \"%s\" because you do not have the appropiate permissions for that account. Either enter the name as a required or optional attendee or talk to your administrator about giving you permission to schedule \"%s\".").sprintf(name, name, name));
				break;
			case 2:
				alert(_("\"%s\" has declined your meeting because \"%s\" does not automatically accept meeting requests. ").sprintf(name, name));
				break;
			case 3:
				alert(_("\"%s\" has declined your meeting because it is recurring. You must book each meeting separetly with this recurrence.").sprintf(name));
				break;
			case 4:
				alert(_("\"%s\" is already booked for this specified time. You must use another time or find another resource.").sprintf(name));
				break;
			default:
				//alert(_("Unable to directly book a resource for this meeting."));
				alert(_("Meeting was not scheduled.").sprintf(name));
				break;
		}
	}
	module.saving = false;
	module.savingMeetingRequest = false;
}
