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

var PinAssistant = Class.create({
	
	// TODO: remove this mapping once the framework provides
	// a more robust method of mapping/converting a character to a number
	numericMap: {
		e:'1',r:'2',t:'3',
		d:'4',f:'5',g:'6',
		x:'7',c:'8',v:'9',
			'@':'0',
		
		1:'1',2:'2',3:'3',
		4:'4',5:'5',6:'6',
		7:'7',8:'8',9:'9',
			  0:'0'
	},
	
	initialize: function(mode, mainassistant) {
		this.mode = mode;
		this.mainAssistant = mainassistant;
	},
	
  	setup: function() {	
	
		this.bodyClassName = this.controller.document.body.style.background;
		this.controller.document.body.style.background = "#606060";
		
		Mojo.listen($('zero_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '0'));
		Mojo.listen($('one_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '1'));
		Mojo.listen($('two_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '2'));
		Mojo.listen($('three_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '3'));
		Mojo.listen($('four_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '4'));
		Mojo.listen($('five_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '5'));
		Mojo.listen($('six_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '6'));
		Mojo.listen($('seven_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '7'));
		Mojo.listen($('eight_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '8'));
		Mojo.listen($('nine_button'), Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, '9'));
		Mojo.listen(this.controller.get('backspace'), Mojo.Event.tap, this.onDeletePress.bindAsEventListener(this));
		
		this.buttonModel = {
			buttonLabel: $L('Cancel'),
			disabled: false
		};
   		Mojo.listen($('cancel_pin'), Mojo.Event.tap, this.cancel.bindAsEventListener(this));
		Mojo.listen($('done_pin'), Mojo.Event.tap, this.testPin.bindAsEventListener(this));
			
		this.pinKeyPressHandler = this.onPinKeyPress.bindAsEventListener(this);	
		Mojo.listen(this.controller.sceneElement, Mojo.Event.keypress, this.pinKeyPressHandler);
				
		this.dsAttributes = {
			modelProperty: 'pin',
			maxLength: 30,
		};
		this.pinModel = {
		    'pin': '',
			disabled: true
			
		};
		this.controller.setupWidget('pinfield', this.dsAttributes, this.pinModel);
				
		var appMenuModel = {
	        visible: true,
	        items: [Mojo.Menu.editItem,{label:$L('Help'), command:Mojo.Menu.helpCmd}
	            ]
	        };
		this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems:true}, appMenuModel);	
		
		this.setPolicyInstructions();
		
  	},
	
	
	cleanup:function(){
		this.controller.document.body.style.background=this.bodyClassName;
	},
	
	handleCommand: function(event) {
		if(!event)
			return;
		if (event.type == Mojo.Event.back) {
			this.cancel();
		}
		else if (event.type == Mojo.Event.command) {
			if(event.command == Mojo.Menu.helpCmd) {
				new Mojo.Service.Request('palm://com.palm.applicationManager', {
					method: 'open',
					parameters: {'id': 'com.palm.app.help',params: {'target': 'http://help.palm.com/screen/index.html'}}});
			}
		}	

	},
			
	cancel: function() {
		if(this.mode == "enterPin")
			this.mainAssistant.setPinCode('');
		else
			this.mainAssistant.pinVerified(false);
		Mojo.Controller.stageController.popScene();
	},
	
	updatePinFields: function(value) {
		
		if (this.pinModel.pin.length == 29) {
			return;
		}
		this.pinModel.pin = this.pinModel.pin+value;
		this.controller.modelChanged(this.pinModel, this);
	},
	
	clearPinField: function(clearAll) {
		
		var len =this.pinModel.pin.length; 
		if(clearAll) {
			this.pinModel.pin= '';
			this.controller.modelChanged(this.pinModel, this);
		}
		else if(len>0){
			this.pinModel.pin=this.pinModel.pin.slice(0,len-1);
			this.controller.modelChanged(this.pinModel, this);
		}
	},
  	
	onNumberPress: function(event, number) {
		Event.stop(event);
		if(this.retry) {
			$('pin-title-big').innerHTML = $L('Enter PIN');
			this.setPolicyInstructions();
			this.retry = false;
		}
		this.updatePinFields(number);
	},
	
	onPinKeyPress: function(event) {
		Event.stop(event);
		var code = event.originalEvent.keyCode;
		var c = String.fromCharCode(code).toLowerCase();
		var numeric = this.numericMap[c];
		if(this.retry) {
			$('pin-title-big').innerHTML = $L('Enter PIN');
			this.setPolicyInstructions();
			this.retry = false;
		}
		
		if (Mojo.Char.isDeleteKey(code)) {
			this.clearPinField(false);
		}
		else if (Mojo.Char.isEnterKey(code)) {
			this.testPin();
		}
		else if (numeric != null) {
			this.updatePinFields(numeric);
		}
	},
	
	onDeletePress: function(event) {
		event.stop();
		this.clearPinField(false /* only clear last */);
	},

	
	testPin: function() {
				
		var payload = {passCode: ''};
		payload.passCode = this.pinModel.pin;
		
		if(payload.passCode === '')
			return;
		
		if(this.mode === "enterPin") {
			if(!this.firstAttempt) {
				this.firstAttempt = payload;				
				$('pin-title-big').innerHTML = $L('Enter PIN Again');
				$('pin-title-small').innerHTML = '';
				this.clearPinField(true);
			}
			else {
				if(this.firstAttempt.passCode === payload.passCode) {
					if (this.mainAssistant.securityPolicy) {
						this.setSystemlockModeReq = SystemService.setSystemlockValue('pin',payload.passCode, this.handleSetPasscodeResponse.bind(this));
					}
					else {
						this.mainAssistant.setPinCode(payload.passCode);
						Mojo.Controller.stageController.popScene();
					}
				}
				else {
					$('pin-title-big').innerHTML = $L("PIN doesn't match");
					$('pin-title-small').innerHTML = $L("Try again");
					delete this.firstAttempt;
					this.retry = true;
					this.clearPinField(true);
				}
			}
		}
		else if(this.mode === "verifyPin" || this.mode === "changePin") {
			this.buttonModel.disabled = true;
			this.controller.modelChanged(this.buttonModel);
			this.testPinRequest = new Mojo.Service.Request('palm://com.palm.systemmanager', {
				method: 'matchDevicePasscode',
				parameters: payload,
				onSuccess: this.onTestPinSuccess.bind(this),
				onFailure: this.onTestPinFailure.bind(this)
			});
		}
	},
	
	onTestPinSuccess: function(response) {
		
		this.buttonModel.disabled = false;
		this.controller.modelChanged(this.buttonModel);		
		this.clearPinField(true);
				
		if (response.returnValue) {
			if (this.mainAssistant.securityPolicy) 
				this.mainAssistant.retriesLeft = this.mainAssistant.maxRetries;
			if(this.mode == "changePin") {
				this.mode = "enterPin";
				delete this.firstAttempt;
				$('pin-title-big').innerHTML = $L('Enter New PIN');
				this.setPolicyInstructions();
			}
			else if(this.mode == 'verifyPin') {
				this.mainAssistant.pinVerified(true);
				Mojo.Controller.stageController.popScene();
			}			
		}		
	},
	
	onTestPinFailure: function(response) {
		
		this.buttonModel.disabled = false;
		this.controller.modelChanged(this.buttonModel);		
		this.clearPinField(true);
		
		if (!response.returnValue) {
			if (this.mainAssistant.securityPolicy) {
				$('pin-title-big').innerHTML = $L('PIN Incorrect');
				this.mainAssistant.retriesLeft = response.retriesLeft;
				if(response.retriesLeft === 1) {
					$('pin-title-small').innerHTML = $L('');
					this.showErrorDialog();
				}
				else {
					this.controller.get('pin-title-small').innerHTML = Mojo.Format.formatChoice(response.retriesLeft, $L("1##{num} try remaining.|##{num} tries remaining."), {
																		num: SystemService.numberToWord(response.retriesLeft)});
				}
			}
			else {
				$('pin-title-big').innerHTML = $L('PIN Incorrect');
				$('pin-title-small').innerHTML = $L('Try Again');
			}		
		}
	},
	
	handleSetPasscodeResponse: function(response) {
		if (response.returnValue) {
			this.mainAssistant.pinAlreadySet();
			Mojo.Controller.stageController.popScene();
		}
		else {
			this.clearPinField(true);
			$('pin-title-big').innerHTML = $L('PIN Incorrect');
			$('pin-title-small').innerHTML = $L('PIN does not match security requirements.');
			this.retry = true;
		} 
		
	},
	
	showErrorDialog: function() {
		this.controller.showAlertDialog({
			onChoose : function(value) {},
			title: $L('PIN Incorrect'),
			message: $L('If you enter an incorrect PIN now your phone will be erased.'),
			choices:
			[{
				label: $L('Continue'),
				type: "dismiss",
				value: 'dismissed'
			}]
		});
	},
	
	setPolicyInstructions: function() {
		if(this.mode == 'enterPin') {
			if (this.mainAssistant.securityPolicy && this.mainAssistant.securityPolicyObj.password.minLength > 1) {
				$('pin-title-small').innerHTML = $L("PIN must be at least #{minLength} numbers").interpolate(this.mainAssistant.securityPolicyObj.password);
			}
			else 
				$('pin-title-small').innerHTML = '';
		}
		else if(this.mode === "verifyPin" || this.mode === "changePin") {
			if (this.mainAssistant.securityPolicy && this.mainAssistant.retriesLeft == 1) {
				this.showErrorDialog();
			}
		}		
	}
	
});
