/* Copyright 2009 Palm, Inc.  All rights reserved. */

var Email = Class.create({
	initialize: function(){
		this.summary = "";
		this.text = Email.kSignaturePlaceholder;
		this.originalText = "";
		this.recipients = [];
		this.action= "";
		this.id = -1;
		this.attachments = [];
		this.inlineAttachments = [];
	},
	
	/**
	 * Take the JSON-formatted parameters that were sent to the new stage
	 * and incorporate them into the email object
	 */
	evalParams: function(emailDetails) {
		if (emailDetails.id) {
			var id = parseInt(emailDetails.id);
			if (id > 0) {
				this.id = id;
			} else {
				Mojo.Log.error("Email.evalParams ignoring invalid id", emailDetails.id);
			}
		}

		if (emailDetails.account) {
			var account = parseInt(emailDetails.account);
			if (account > 0) {
				this.account = account;
			} else {
				Mojo.Log.error("Email.evalParams ignoring invalid account", emailDetails.account);
			}
		}

		if (emailDetails.summary) {
			this.summary = emailDetails.summary;
		}

		if (emailDetails.text) {
			this.text = emailDetails.text + Email.kSignaturePlaceholder;
		}

		// TODO: this should perform validation/fixup on the recipients
		if (emailDetails.recipients) {
			if (Object.isArray(emailDetails.recipients)) {
				this.recipients = emailDetails.recipients;
			} else {
				Mojo.Log.error("Email.evalParams ignoring badly formed recipients", emailDetails.recipients);
			}
		}

		if (emailDetails.attachments) {
			if (Object.isArray(emailDetails.attachments)) {
				this.attachments = emailDetails.attachments;
			} else {
				Mojo.Log.error("Email.evalParams ignoring badly formed attachments", emailDetails.attachments);
			}
		}

		if (emailDetails.inlineAttachments) {
			if (Object.isArray(emailDetails.inlineAttachments)) {
				this.inlineAttachments = emailDetails.inlineAttachments;
			} else {
				Mojo.Log.error("Email.evalParams ignoring badly formed inline attachments", emailDetails.inlineAttachments);
			}
		}

		if (emailDetails.timeStamp) {
			this.timeStamp = emailDetails.timeStamp;
		}

		if (emailDetails.priority) {
			this.priority = emailDetails.priority;
		}

		if (emailDetails.flags) {
			this.flags = emailDetails.flags;
		}
	},
	
	/**
	 * fill in the email object from the mailto uri
	 */
	evalMailto: function(uri) {
		var parser = new MailtoURIParser(uri);
		this.summary = parser.getDecodedSubject();
		this.text = parser.getDecodedBody() + Email.kSignaturePlaceholder;
		
		var recipArray = [];
		var toStr = parser.getDecodedTO();
		var toRecips = toStr.split(/[,;]/);
		toRecips.each(function(r) {
			if (r.length > 0) {
				var newRecip = new Object();
				newRecip.type = 'email';
				newRecip.role = EmailRecipient.roleTo;
				newRecip.value = r;
				newRecip.contactDisplay = r.escapeHTML();
				recipArray.push(newRecip);
			}
		});
		
		var ccStr = parser.getDecodedCC();
		var ccRecips = ccStr.split(/[,;]/);
		ccRecips.each(function(r) {
			if (r.length > 0) {
				var newRecip = new Object();
				newRecip.type = 'email';
				newRecip.role = EmailRecipient.roleCc;
				newRecip.value = r;
				newRecip.contactDisplay = r.escapeHTML();
				recipArray.push(newRecip);
			}
		});
		
		var bccStr = parser.getDecodedBCC();
		var bccRecips = bccStr.split(/[,;]/);
		bccRecips.each(function(r) {
			if (r.length > 0) {
				var newRecip = new Object();
				newRecip.type = 'email';
				newRecip.role = EmailRecipient.roleBcc;
				newRecip.value = r;
				newRecip.contactDisplay = r.escapeHTML();
				recipArray.push(newRecip);
			}
		});
		
		this.recipients = recipArray;
	},

	createCommon: function(original, login, subjectPrefix) {
		this.id = original.id;
		this.replyMessage = original.messageId;
		// Check if 're:' or 'fw:' needs to be added to subject
		var subjectStartsWith = original.summary.substring(0, subjectPrefix.length).toLowerCase();
		if (subjectStartsWith === subjectPrefix.toLowerCase()) {
			this.summary = original.summary;
		} else {
			this.summary = subjectPrefix + original.summary;
		}

		if (original.text && original.text.length > 0) {
			var fromObj;
			var toAddressList = [];
			var ccAddressList = [];
			original.recipients.each(function(r) {
					if (r.role === EmailRecipient.roleFrom) {
						if (!r.displayName) {
							r.displayName = r.value;
						}
						fromObj = r;
					} else if (r.role === EmailRecipient.roleTo) {
						if (r.displayName) {
							var toStr;
							if (r.displayName === r.address) 
								toStr = r.displayName;
							else 
								toStr = "#{displayName} <#{address}>".interpolate(r);
							toAddressList.push(toStr);
						}
					} else if (r.role === EmailRecipient.roleCc) {
						if (r.displayName) {
							var ccStr;
							if (r.displayName === r.address) 
								ccStr = r.displayName;
							else 
								ccStr = "#{displayName} <#{address}>".interpolate(r);
							ccAddressList.push(ccStr);
						}
					}
			});

			this.text = Email.kReplyForwardSetupElems;
			if (this.action === "forward") {
				if (fromObj.displayName === fromObj.address) {
					this.text += $L("<b>From:</b> ") + "#{displayName}".interpolate(fromObj).escapeHTML() + "<br/>";
				}
				else {
					this.text += $L("<b>From:</b> ") + "#{displayName} <#{address}>".interpolate(fromObj).escapeHTML() + "<br/>" 
				};
				this.text += $L("<b>Date:</b> ") + Mojo.Format.formatDate(new Date(parseInt(original.timeStamp)), {date:'medium', time:'short'}) + "<br/>";
				this.text += $L("<b>Subject:</b> #{summary}").interpolate(original) + "<br/>";
				if (toAddressList.length > 0) {
					this.text += $L("<b>To:</b> ") + "#{list}".interpolate({list:toAddressList.join("; ")}).escapeHTML() + "<br/>";
				}
				if (ccAddressList.length > 0) {
					this.text += $L("<b>CC:</b> ") + "#{list}".interpolate({list:ccAddressList.join("; ")}).escapeHTML() + "<br/>";
				}
				this.text += "<br/>";
			} else {
				
				// reply case. Integrate header info with sentence
				var strArgs = {
					"monthDate": "",
					"displayName": fromObj.displayName,
					"address": fromObj.address
				};
				if (original.timeStamp) {
					// <Month (short version)> <Day>,<Year> at <time>
					strArgs.monthDate = Mojo.Format.formatDate(new Date(parseInt(original.timeStamp, 10)), {date:'medium', time:'short'});
					this.text += $L("On #{monthDate}, #{displayName} <#{address}> wrote: ").interpolate(strArgs).escapeHTML();
				} else {
					this.text += $L("#{displayName} <#{address}> wrote: ").interpolate(strArgs).escapeHTML();
				}
				this.text += "<br><br>";
			}
			this.originalText = original.text;
		} else {
			this.text = "";
			this.originalText = "";
		}

		if (login) {
			this.login = login;
		}
	},

	createReply: function(original, login) {
		this.action = "reply";
		if (login) {
			login = login.toLowerCase();
		} else {
			Mojo.Log.error("Email.createReply got login="+login)
			login = "";
		}
		this.createCommon(original, login, Email.kSubjectPrefixRe);

		if (original.recipients) {
			var originalSender;
			original.recipients.each(function(r) {
				// Only replying to the 'from' person. All others dropped
				if (r.role === EmailRecipient.roleReplyTo) {
					originalSender = Object.clone(r);
					originalSender.role = EmailRecipient.roleTo;
				}
				else if (r.role === EmailRecipient.roleFrom && originalSender === undefined) {
					originalSender = Object.clone(r);
					originalSender.role = EmailRecipient.roleTo;
				}
			});

			this.recipients = [originalSender];
		}
		
		this.inlineAttachments = original.inlineAttachments;
	},
	
	createReplyAll: function(original, login) {
		this.action = "replyAll";
		if (login) {
			login = login.toLowerCase();
		} else {
			Mojo.Log.error("Email.createReplyAll got login="+login)
			login = "";
		}
		this.createCommon(original, login, Email.kSubjectPrefixRe);

		if (original.recipients) {
			// Get the email address for the current account. In most cases, it is the same
			// as the login, but for EAS, it is embedded within parenthesis.
			var emailRegExp = /\(([\w\-\.\@]+)\)/.exec(login);
			var thisAccount = login;
			if (emailRegExp && emailRegExp.length > 1) {
				thisAccount = emailRegExp[1];
			}

			var recips = [];
			var originalSender;
			original.recipients.each(function(r) {
				if (r.role === EmailRecipient.roleReplyTo) {
					originalSender = Object.clone(r);
					originalSender.role = EmailRecipient.roleTo;
				}
				else if (r.role === EmailRecipient.roleFrom && originalSender === undefined) {
					originalSender = Object.clone(r);
					originalSender.role = EmailRecipient.roleTo;
				}
				else {
					// Add all recipients except our account's address 
					if (r.value.toLowerCase() != thisAccount) {
						recips.push(r);
					}
				}
			});
			
			// Filter out sender from the To list to avoid duplicates
			var originalSenderAddress = originalSender.value.toLowerCase();
			recips = recips.reject(function (r) {
				return (r.role === EmailRecipient.roleTo
				&& r.value.toLowerCase() === originalSenderAddress);
			});
			
			// Put the sender of the original email at the beginning of the To list. 
			recips.unshift(originalSender);
			this.recipients = recips;
		}
		
		this.inlineAttachments = original.inlineAttachments;
	},
	
	createForward: function(original, login) {
		this.action = "forward";
		if (login) {
			login = login.toLowerCase();
		} else {
			Mojo.Log.error("Email.createForward got login="+login)
			login = "";
		}
		this.createCommon(original, login, Email.kSubjectPrefixFw);
		this.attachments = original.attachments;
		this.inlineAttachments = original.inlineAttachments;
	},
	
	saveMessage: function(params, callback, failCallback) {
		// Mark this as a draft
		params.draft = true;
		
		// Quick strip: replace <br> and <p> with newline and then strip all html tags
		var plainText = params.msg.replace(/(<br>|<p>)/g, "\n");
		params.text = plainText.stripTags();

		return new Mojo.Service.Request(Email.identifier, {
				method: 'messageSend',
				parameters: params,
				onSuccess: callback,
				onFailure: failCallback
			});
	},

	sendMessage: function(controller, params, callback, failCallback) {
		// Check for invalid email
		if ((params.to$A == undefined || params.to$A.length == 0) &&
		    (params.cc$A == undefined || params.cc$A.length == 0) &&
		    (params.bcc$A == undefined || params.bcc$A.length == 0)) {
				var e = { message: $L("You must include an address") };
				throw e;
		}

		if (this.action == "forward") {
			Message.setForwarded(this.id, true);
			params.forwardMessage = this.id; 
		}
		else if (this.action == "reply" || this.action == "replyAll") {
			Message.setReplied(this.id, true);
			// No SmartReply in version 1.0
			//params.replyMessage = this.id;
		}

		// Quick strip: replace <br> and <p> with newline and then strip all html tags
		var plainText = params.msg.replace(/(<br>|<p>)/g, "\n");
		params.text = plainText.stripTags();
		
		//console.log("form " + $H(params).inspect());
		controller.serviceRequest(Email.identifier, {
				method: 'messageSend',
				parameters: params,
				onSuccess: callback,
				onFailure: failCallback
			});
	}
});


Email.identifier = 'palm://com.palm.mail';

Email.getPriorityClass = function(priority) {
	/*
	 * See the priority definitions in Email.java
	 */
	if (priority > 3) {
		return Email.LOW_PRIORITY_CLASS;
	}
	if (priority > 0 && priority < 3)  {
		return Email.HIGH_PRIORITY_CLASS;
	}
	return priority;
}

Email.kSignaturePlaceholder = "<span style='font-family:Prelude, Verdana, san-serif;'><br><br></span><span id='signature'></span>";
Email.kReplyForwardSetupElems = "<br><br>" + Email.kSignaturePlaceholder + "<span style='color:navy; font-family:Prelude, Verdana, san-serif; '><hr align='left' style='width:75%'/>";

Email.kSubjectPrefixRe = $L("Re: ");
Email.kSubjectPrefixFw = $L("Fw: ");

Email.LOW_PRIORITY_CLASS = "low-priority";
Email.HIGH_PRIORITY_CLASS = "high-priority";
 

