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

var ComposeAssistant = Class.create({
	initialize : function(params) {
		this.appController = Mojo.Controller.getAppController();
		this.Messaging = this.appController.Messaging;
		this.attachment;
		this.messageTextElement;
		this.prePopulatedRecipients = [];
		this.sendMessageCount = 0;	// keep a count of how many times we call send so we know when the last callback is hit
		this.sentRecipients = [];
		
		var listviewSceneAssistant = this.Messaging.listviewSceneAssistant;
		if (listviewSceneAssistant) {
			this.toggleDebugMenu = listviewSceneAssistant.toggleDebugMenu.bind(listviewSceneAssistant,true);
		}

		this.appMenuAddPictureItem = {label: $L('Attach file...'), command:'addPicture', enabled:true};

		this.appMenuAttrs = {omitDefaultItems: true};	
		this.appMenuModel = { visible:true, label: $L('Chat view menu'), items: [Mojo.Menu.editItem,this.appMenuAddPictureItem,Mojo.Menu.helpItem]};   
	 
		if(params && params.focusWindow)
			this.focusWindow = true;
		else
			this.focusWindow = false;

		if (params) {
			this.launchedWithParams = true;
			
			if (params.launchedAsForward){
				this.launchedAsForward = true;
			}

			Mojo.Log.info("params.attachementType " + params.attachmentType);
			this.passedAttachment = params.attachment || '';
			Mojo.Log.info("passed in attachmentType is " + params.attachmentType);
			this.passedAttachmentType = params.attachmentType;
			if (params.attachment && params.transcodeParams) {
				this.passedTranscodeParams = params.transcodeParams;
			}
			this.passedAttachmentIconPath = params.attachmentIconPath;
			this.messageText = params.messageText || '';
			this.deleteAttachmentWhenDone = params.deleteAttachmentWhenDone;

			// DEPRECATED
			if(params.composeAddress) {
				this.prePopulatedRecipients.push({
					value: params.composeAddress,
					contactDisplay: params.composeAddress,
					type: (params.serviceName ? 'im' : 'phone'),
					serviceName: params.serviceName || ''
				});
			}
			
			/*
			 *	composeRecipients expects the following:
			 *  [
			 *  	{
			 *  		"address": <phone number or IM>,
			 *  		"serviceName": <serviceName or domain> // only required for IM addresses
			 *  	}, ...
			 *  ]
			 */
			if(params.composeRecipients && params.composeRecipients.length) {
				for (var i = 0; i < params.composeRecipients.length; i++) {
					var recipient = params.composeRecipients[i];
					if (recipient.address) {
						this.prePopulatedRecipients.push({
							value: recipient.address,
							contactDisplay: recipient.address,
							type: (recipient.serviceName ? 'im' : 'phone'),
							serviceName: recipient.serviceName || ''
						});
					}
				}
			}
		}
		
		this.considerForSend = this.considerForSend.bind(this);
		this.attachFilePicker = this.attachFilePicker.bind(this);
		this.handleTextAreaChange = this.handleTextAreaChange.bind(this);
		this.handleTextAreaKeyUp = this.handleTextAreaKeyUp.bind(this);
		this.handleCancelAttachment = this.resetTextBox.bind(this,false);		
		this.handleRecipientsChanged = this.handleRecipientsChanged.bind(this);

		this.monkeyPatchAddressingWidget();
		this.saveDraft = true;
	},

  setup: function() {
  	if (!this.launchedWithParams){
  		this.restoreFromDraft();
	}

    this.controller.setupWidget(Mojo.Menu.appMenu, this.appMenuAttrs, this.appMenuModel);

	this.searchList = {
		"property": "to$A",
		"includeEmails": false,
		"includePhones": true,
		"includeIMs": true,
		"includeShortCode": true,
		"hintText": $L('Enter name or number...'),
		"labelText": $L("To:"),
		"focus": true,
		"recipients": this.prePopulatedRecipients,
		"determineTypeFunction": function(str){
			if (str.indexOf("@") > -1) {
				return "email";
			}
			return "phone";
		}
	};

    this.controller.setupWidget('searchList', null, this.searchList);   

	var messageTextWidgetAttributes = {
	    textFieldName: "messageTextElement",
	    hintText: $L('Enter message here...'),
	    multiline: true,
	    focus: false,
	    enterSubmits: true,
		requiresEnterKey: true,
	    modelProperty: "value",
		changeOnKeyPress: true
	};
	this.messageTextWidgetModel = {};
  
    this.controller.setupWidget('messageTextWidget', messageTextWidgetAttributes, this.messageTextWidgetModel);
	
    this.controller.listen('SendButton',Mojo.Event.tap, this.considerForSend);
    this.controller.listen('AttachButton',Mojo.Event.tap, this.attachFilePicker);
    this.controller.listen('cancelAttachment',Mojo.Event.tap, this.handleCancelAttachment);
  },

  ready: function() {
	this.actionButton = this.controller.get('ActionButton');
	this.addressingForm = this.controller.get('addressingForm');
	this.messageTextWidget = this.controller.get('messageTextWidget');
	this.messageTextElement  = this.messageTextWidget.querySelector('[name=messageTextElement]');
	this.addressingWidget = this.controller.get('searchList');
	this.addressingWidgetSpacer = this.controller.get('addressingWidgetSpacer');
	
//	this.addressingWidgetSpacer.setStyle({
//		'height': (Mojo.Environment.DeviceInfo.maximumCardHeight - this.addressingWidget.offsetHeight) + "px"
//	}); 
	
	
	this.messageTextElement.observe('keyup', this.handleTextAreaKeyUp);
	this.messageTextWidget.observe(Mojo.Event.propertyChange, this.handleTextAreaChange);
	
    // Observe add/delete to the addressing widget
    var that = this;
    [Mojo.Event.addressingRecipientAdded,Mojo.Event.addressingRecipientDeleted].each(function(event) {
      that.controller.listen('searchList',event,that.handleRecipientsChanged);
    });	
	
	var charCounterParams = {
		segmentCounter: {
			segmentCountContainer: this.controller.get('segmentCounterContainer'),
			segmentCountElement: this.controller.get('segmentCounter'),
			setTextFieldValueFn: this.setTextFieldValue.bind(this)
		}
	};

	this.characterCounter = new CharacterCounter(this.controller,this.Messaging.messagingPrefs.platformType,this.messageTextElement,charCounterParams);
	this.characterCounter.setSizeParams();
	
	if (this.messageText) {
		this.setTextFieldValue(this.messageText);
	}
	
	if (this.passedAttachment) {
		Mojo.Log.info("passedAttachmentIconPath " + this.passedAttachmentIconPath);
		this.attachFile(this.passedAttachment, this.passedAttachmentIconPath, this.deleteAttachmentWhenDone, this.passedAttachmentType, this.passedTranscodeParams);
	}
  },
  
  considerForSend: function(){
	var message = this.messageTextElement.value.strip();
	if ((!this.attachment && message.length > 0) || this.attachment) {
		if (this.isDebugCommand(message)) {
			return;
		}

		// if the current message is longer than the max size, alert the user and block the send action
		if (!this.characterCounter.isValidLength()) {
			this.controller.showAlertDialog({
				onChoose: function(){
				},
				title: $L("Message length error"),
				message: $L("The message that you have entered is larger than the allowed size."),
				preventCancel: false,
				choices: [{
					label: $L('Ok'),
					value: 'Close'
				}]
			});
			return;
		}
		var recipientsArray = Mojo.View.serializeMojo(this.addressingForm, true).to$A;

		if ($A(recipientsArray).length > 0) {
			var phoneRecipients = [];
			var imRecipients = [];
			// separate the different types of recipients
			for(var x=0; x<recipientsArray.length; x++) {
				var recipient = recipientsArray[x];
				if (recipient.serviceName) {
					// make sure that the serviceName is supported
					var isSupported = this.Messaging.isIMAccountTypeSupported(recipient.serviceName);
					if(!isSupported.returnValue) {
						var errorMessage = '';
						if(!isSupported.isSupportedType) {
							errorMessage = $L("You are attempting to send to an IM type that is not supported.  Please choose a different address.");
						} else if(!isSupported.hasAccount) {
							errorMessage = $L("You are attempting to send to an IM type for which you do not have an account to send from.");
						}
						
						this.controller.showAlertDialog({
							onChoose: function(){},
							title: $L("Unable to send"),
							message: errorMessage,
							preventCancel: false,
							choices: [{
								label: $L('Ok'),
								value: 'Close'
							}]
						});
						return;
					}
					imRecipients.push(recipient);
				} else {
					phoneRecipients.push(recipient);
				}
			}

			// send to phone recipients
			if (phoneRecipients.length > 0) {
				var segmentData = this.characterCounter.getSegmentData();
				if (segmentData.segmentCount) {
					for (var x = 0; x < segmentData.segmentCount; x++) {
						this.sendMessage(phoneRecipients, segmentData.segments[x]);
						this.sendMessageCount++;
					}
				}
			}

			// send to IM recipients, don't segment the data for IM
			if(imRecipients.length > 0) {
				this.sendMessage(imRecipients, message);
				this.sendMessageCount++;
			}

			this.sentRecipients = recipientsArray;
			this.resetTextBox(true);
		} else {
			this.controller.showAlertDialog({
				onChoose: function(){
				},
				title: $L("Please choose a recipient."),
				choices: [{
					label: $L('Done'),
					value: 'Ok'
				}]
			});
		}
	}     
  },
  
	sendMessage: function(recipientsArray,message) {
		if(!this.handleSentMessageResponse) {
			this.handleSentMessageResponse = this._handleSentMessageResponse.bind(this);
		}
		var params = {
			recipientJSONArray: recipientsArray,
     		messageText: message,
      		onSuccess: this.handleSentMessageResponse
		};
		if (this.attachment) { // sending an attachment
			params.attachment = this.attachment;
			params.transcodeParams = this.transcodeParams;
			//params.summary = $L('New picture message');
			params.summary = '';
			params.deleteAttachmentWhenDone = this.deleteAttachmentWhenDone;
		}
		this.actionButton.addClassName('invisible');
		this.saveDraft = false;
		MessagingMojoService.sendMessageFromCompose(this.controller, params); 
	},
  
  _handleSentMessageResponse: function (result) {
  	if (--this.sendMessageCount == 0) {
		if(this.sentRecipients.length == 1) {
			this.controller.stageController.swapScene({name:'chatview', transition:Mojo.Transition.crossFade}, result.chatThreadId);
		} else {
			// if we have multiple recipients, just pop this scene + set the current view to be the history view
			this.Messaging.setListViewVisible(this.Messaging.Views.HISTORY);
			if(!MessagingUtils.sceneExistsInStack(this.controller.stageController,'listview')) {
				this.appController.assistant.getListChunk(this.controller,this.handleListChunkOnPop.bind(this));
			} else {
				this.controller.stageController.popScenesTo('listview');
			}			
		}
		this.setTextFieldValue("");
	}
  },
  
	isDebugCommand: function(message) {
		if(message == "--palmDebug" && !Mojo.View.serializeMojo(this.addressingForm, true).to$A) {
			this.toggleDebugMenu();
			this.controller.stageController.popScene();
			this.controller.stageController.pushScene('debug');
			return true;
		}
		return false;
	},

	setTextFieldValue: function(value) {
		if(value != undefined) {
			this.messageTextWidgetModel.value = value;
			this.controller.modelChanged(this.messageTextWidgetModel);
			// make sure the right action button is showing if there is any text in the textbox
			this.handleTextAreaChange();			
		} 
	},

	handleTextAreaKeyUp: function(event) {
		if (event && Mojo.Char.isEnterKey(event.keyCode)) {
			this.considerForSend();
			Event.stop(event);
		}		
	},

	handleTextAreaChange: function() {
		if (this.messageTextElement && this.messageTextElement.value == '') {
			this.actionButton.removeClassName('textentry');
			this.actionButton.addClassName('empty');
		} else {
			this.actionButton.addClassName('textentry');
			this.actionButton.removeClassName('empty');
		}
		
		this.characterCounter.deferredResetCount();	
	},

  attachFilePicker: function(event) {   
  
    Mojo.Log.info("++++++ maxMessageAttachmentSize " + this.Messaging.carrierSettings.mmscMessageSizeLimit);
    var params = {
		actionType: 'attach',
        kinds: ['image','video'], // TODO: integrate other media types
        defaultKind: 'image',
		maxVideoSize: this.Messaging.carrierSettings.mmscMessageSizeLimit,
		tempVideoFilePath: '/media/internal/.attachments/mms/mmsVideo1',
        onSelect: this.handleFilePickerSelect.bind(this)
    };
    Mojo.FilePicker.pickFile(params,this.controller.stageController);  
  },
  
  handleFilePickerSelect: function(file) {
		
		//"crossApp1262900390599", "callbackParams": [ { "select": { "fullPath": "\/media\/internal\/DCIM\/100PALM\/CIMG0002.mp4", "iconPath": "\/var\/luna\/data\/extractfs\/media\/internal\/DCIM\/100PALM\/CIMG0002.mp4:621790:17423:75:64:3", "size": "639213", "isTmpVideoFile": false } } ] }] 

		this.attachFile(file.fullPath, file.iconPath, file.isTmpVideoFile, file.attachmentType, file.transcodeParams);
		
  },

  attachFile: function(imagePath,displayPath, isTmpVideoFile, attachmentType, transcodeParams) {
		if (imagePath) {
			Mojo.Log.info("attachmentType is " + attachmentType);
			var lowerCaseImagePath = imagePath.toLocaleLowerCase();
			if (attachmentType == "video") {

				if ((!displayPath) || (displayPath.length === 0) ){
					Mojo.Log.info("Using Generic video attachment icon as none specified by caller");	
					displayPath = Mojo.appPath + "images/compose-attachment-video.png";
				}
				//displayPath = displayPath;
			} else if ( (lowerCaseImagePath.endsWith(".jpg")) ||
						((lowerCaseImagePath.endsWith(".jpeg"))) ||
						((lowerCaseImagePath.endsWith(".png"))) ){
					//always use extractfs for images, even if iconPath came in		
					Mojo.Log.info("attached a JPG/PNG image");
					displayPath = MessagingUtils.extractfs(imagePath,{width:200,height:100,crop:3});
			}else{
				if (!displayPath){
					if (imagePath.endsWith('.vcf')){
						Mojo.Log.info("VCard attachment");
						displayPath = Mojo.appPath + "images/compose-attachment-vcard.png";
					}else{
						Mojo.Log.info("Generic attached");
						displayPath = Mojo.appPath + "images/compose-attachment-generic.png";
					}
					
				}
			}
			
			this.controller.get('attachmentContainer').show();
			this.actionButton.addClassName('textentry');
			this.actionButton.removeClassName('empty');
			this.controller.get('attachmentImage').src = displayPath;
			this.attachment = imagePath;
			if (transcodeParams !== undefined) {
				this.transcodeParams = transcodeParams;
			}
			this.deleteAttachmentWhenDone = isTmpVideoFile;
			this.searchList.includeIMs = false;
			this.controller.modelChanged(this.searchList);
			this.characterCounter.setSizeParams();
		}
	},

  resetTextBox: function(resetValue){
    if (resetValue == true) {
	  this.setTextFieldValue("")
    }
    if (this.messageTextElement.value.length == 0) {
		this.actionButton.removeClassName('textentry');
		this.actionButton.addClassName('empty');
		this.characterCounter.resetCount();
	}
    this.controller.get('attachmentContainer').hide();
    this.controller.get('attachmentImage').src = "";   
    this.attachment = null;  
    this.searchList.includeIMs = true;  
    this.controller.modelChanged(this.searchList);  
	this.setCharacterCounterMaxLength();  
  },

  handleRecipientsChanged: function() {
	var recipientsArray = Mojo.View.serializeMojo(this.addressingForm, true).to$A;
    // iterate through recipients and determine if we have an IM contact
    var hasIM = false;
	if (recipientsArray) { 
		for(var i=0; i<recipientsArray.length && !hasIM; i++) {
			if (recipientsArray[i].serviceName) {
				hasIM = true;
			}
		}
	}
    // Hide the attach button if there is an IM contact
    if(hasIM == true) {         
      this.hideAttachButton();
    } else {                  
      this.showAttachButton();
    }
	this.setCharacterCounterMaxLength();
  },
  
  cleanup: function() {
	this.saveToDraft();
  	
    var that = this;
	
    this.controller.stopListening('SendButton',Mojo.Event.tap, this.considerForSend);
    this.controller.stopListening('AttachButton',Mojo.Event.tap, this.attachFilePicker);
    this.controller.stopListening('cancelAttachment',Mojo.Event.tap, this.handleCancelAttachment);	
	
    [Mojo.Event.addressingRecipientAdded,Mojo.Event.addressingRecipientDeleted].each(function(event) {
      that.controller.stopListening('searchList',event,that.handleRecipientsChanged);
    });
	
	this.messageTextElement.stopObserving('keyup', this.handleTextAreaKeyUp);
	this.messageTextWidget.stopObserving(Mojo.Event.propertyChange, this.handleTextAreaChange);
	
	this.characterCounter.destroy();
  },

  activate: function() {
	if(this.focusWindow) {
		this.focusWindow = false;
		this.controller.stageController.activate();
	}  	
  },
  
  deactivate: function() {
  },

	handleCommand: function(event) {
		if(event.type == Mojo.Event.command) {
			if(event.command == 'addPicture') {
				this.attachFilePicker();
				event.stop();
			} 
		} else if(event.type == Mojo.Event.back) {
			if (this.launchedAsForward === undefined) {
				event.stop();
				this.saveDraft = false;
				if(!MessagingUtils.sceneExistsInStack(this.controller.stageController,'listview')) {
					this.appController.assistant.getListChunk(this.controller,this.handleListChunkOnPop.bind(this));
				} else {
					this.controller.stageController.popScenesTo('listview');
				}
				return;
			}
		}
	},
	
	handleListChunkOnPop: function(forceListView,result) {
		this.controller.stageController.popScenesTo('listview');
		this.controller.stageController.pushScene('listview',{forceListView:forceListView, listDataChunk:result});
	},
  
  showAttachButton: function() {
    this.controller.get('AttachButton').show();
    this.appMenuAddPictureItem.disabled = false;
    this.controller.modelChanged(this.appMenuAddPictureItem);      
  },
  
  hideAttachButton: function() {
    this.controller.get('AttachButton').hide();
    this.appMenuAddPictureItem.disabled = true;
    this.controller.modelChanged(this.appMenuAddPictureItem);      
  },
  
	setCharacterCounterMaxLength: function() {
		var recipientsArray = Mojo.View.serializeMojo(this.addressingForm, true).to$A;
		var hasPhoneNumber = false;
		var hasEmail = false;
		var longestEmailAddress = "";

		if(recipientsArray) {
			for(var i=0; i<recipientsArray.length; i++) {
				var recipient = recipientsArray[i];
				
				if(!recipient.serviceName) {
					if(recipient.value.indexOf("@") > -1) {
						hasEmail = true;
						if(recipient.value.length > longestEmailAddress.length) {
							longestEmailAddress = recipient.value;
						}						
					} else {
						hasPhoneNumber = true;
					}
				}
			}
		}
		var params = {
			maxPartLength: 1000,
			maxParts: 1,
			headerSize: 0,
			encodings:""
		};
		if (!this.attachment) {
			if (hasPhoneNumber && !hasEmail) { // SMS
				params.maxPartLength = this.Messaging.carrierSettings.smsMessageSizeLimit;
				params.maxParts = this.Messaging.carrierSettings.smsMaxPartsPerMessage;
				params.headerSize = this.Messaging.carrierSettings.smsHeaderSizeLimit;
			} else if (hasEmail) { // SMS to email
				params.maxPartLength = (this.Messaging.carrierSettings.smsMessageSizeLimit - (longestEmailAddress.length + 1));
				params.maxParts = 1;
				params.headerSize = 0;
			}
			
			params.encodings = this.Messaging.carrierSettings.smsEncoding;
		}
		
		this.characterCounter.setSizeParams(params);	
	},
	
	saveToDraft: function(data) {
		if (this.saveDraft === true) {
			var recipientsArray = Mojo.View.serializeMojo(this.addressingForm, true).to$A;
			var message = this.messageTextElement.value.strip();
			var x = new Mojo.Service.Request(MessagingMojoService.identifier, {
				method: 'saveComposeAsDraft',
				parameters: {
					recipientJSONArray: recipientsArray,
					messageText: message,
					attachment: this.attachment
				}
			});
		}
	},
	
	restoreFromDraft: function() {
		// Only restore if this is compose was initiated by the user 
		if (this.launchedAsForward === undefined && 
			(this.messageText === undefined || this.messageText.length === 0) &&
			this.prePopulatedRecipients.length === 0) {
			this.controller.serviceRequest(MessagingMojoService.identifier, {
				method: 'restoreComposeFromDraft',
				parameters: {},
				onSuccess: function(resp) {
					Mojo.Log.info("restoreFromDraft %j", resp);
					this.controller.get('searchList').mojo.updateRecipients(resp.recipientJSONArray);
					this.setTextFieldValue(resp.messageText);
					if (resp.attachment && resp.attachment.length > 0) {
						this.attachFile(resp.attachment);
					}
				}.bind(this)
			});
		}
	},

	/*******
	 * Monkey patch the addressing widget if the carrier requires limiting recipients
	 *******/
	monkeyPatchAddressingWidget: function() {
		if (this.Messaging.carrierSettings && this.Messaging.carrierSettings.smsMaxRecipients > 0) {
			Mojo.Log.warn("carrierSettings.smsMaxRecipients=%i, monkey patching addRecipients", this.Messaging.carrierSettings.smsMaxRecipients);

			Mojo.Widget.AddressingWidget.prototype.maxRecipients = this.Messaging.carrierSettings.smsMaxRecipients;
			Mojo.Widget.AddressingWidget.prototype.addRecipient = function(recip) {
				try {
					if (this.totalRecips >= this.maxRecipients) {
						if (this.showingMaxRecipientsDlg !== true) {
							this.showingMaxRecipientsDlg = true;
							var messageText = $L("There is a maximum of #{maxRecipients} recipients per message.").interpolate(this);
							this.controller.scene.showAlertDialog({
								onChoose: function() { this.showingMaxRecipientsDlg = false}.bind(this),
								title: $L("Unable to add recipient"),
								message: messageText,
								choices: [{ label: $L('Dismiss'), value: 'dismiss' }]
							});
						}
						return;
					}
				} catch (e) {
					Mojo.Log.logException(e, "Messaging.addRecipient")
				}
				var content, element;
				var recipDiv;
				
			  	//do 2 things when a user adds a recipient:
			  	//1) create the "pretty view" based on the recipient.html template
			  	//2) create the real info view based on the recipient-info.html template
				if (recip.personId) {
					recip.alreadyValidated = true;
				}
			  	recip.prefix = this.prefix;
			  	recip.identifier = Mojo.View.makeUniqueId();	
				
			  	content = Mojo.View.render({object: recip, template: Mojo.Widget.getSystemTemplatePath("/addr-widget/recipient")});
			  	element = this.recipientArea.insert({bottom: content}); //add these between the input box and "to"	
			  	this.resetTextFieldValue();
				recipDiv = this.controller.get(recip.identifier);
				
				//set json for this field
				this._setJsonRecip(recip, recipDiv);
				
			  	if (!recip.alreadyValidated && this._validateRecipient(recip, recipDiv)) {
			  	  this._reverseLookup(recip, recipDiv);
			  	}
				Mojo.Event.send(this.controller.element, Mojo.Event.addressingRecipientAdded);
				this.totalRecips++;
			}
		}
	}
});
