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

var CalculatorAssistant = Class.create({

	appMenuModel: { visible:true, 
					label: $L('Calculator'), 
					items: [{label:$L('Edit'), items: [{label:$L('Cut'), command:Mojo.Menu.cutCmd, shortcut:'x', disabled:true},
	                								   {label:$L('Copy'), command:Mojo.Menu.copyCmd, shortcut:'c', disabled:true}, 
	                								   {label:$L('Paste'), command:Mojo.Menu.pasteCmd, shortcut:'v', disabled:true}]
							},
							{label:$L('Help'), command:Mojo.Menu.helpCmd, disabled:false}]
				  },

  	initialize : function(calculator) {
    	console.log("CalculatorAssistant#initialize");
		this.calculator = calculator;
		this.optionKeys = false;
  	},
  
  	setup: function() {
		this.setupTapHandlers();
		document.observe('keypress', this.onKeyPress.bindAsEventListener(this));
		
		// JIRA NOV-52270
		Mojo.Event.listen(this.controller.document, "keydown", this.onKeyDown.bindAsEventListener(this), true);
		
		// Set the maximum number of digits we can display in the results div
		this.setResultsDisplayLength(11); 
		$('resultsText').focus();
		
		if (this.calculator.getMemValue())
			this.showMemoryIndicator();
			
		if (Mojo.Format.getFormatHash().numberDecimal == ',') {
			$('decimal').down().addClassName('comma');
		}
		
		this.calculator.clear();
		this.updateResults();
		
		this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems:true}, this.appMenuModel);
  	},
	
	setupTapHandlers: function() {
		$('zero').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 0));
		$('one').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 1));
		$('two').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 2));
		$('three').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 3));
		$('four').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 4));
		$('five').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 5));
		$('six').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 6));
		$('seven').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 7));
		$('eight').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 8));
		$('nine').observe(Mojo.Event.tap, this.onNumberPress.bindAsEventListener(this, 9));
		
		$('decimal').observe(Mojo.Event.tap, this.onDecimalPress.bindAsEventListener(this));
		$('divide').observe(Mojo.Event.tap, this.onDividePress.bindAsEventListener(this));
		$('multiply').observe(Mojo.Event.tap, this.onMultiplyPress.bindAsEventListener(this));
		$('subtract').observe(Mojo.Event.tap, this.onSubtractPress.bindAsEventListener(this));
		$('add').observe(Mojo.Event.tap, this.onAddPress.bindAsEventListener(this));
		$('equals').observe(Mojo.Event.tap, this.onEqualsPress.bindAsEventListener(this));
		$('clear').observe(Mojo.Event.tap, this.onClearPress.bindAsEventListener(this));
		$('backspace').observe(Mojo.Event.tap, this.onBackspacePress.bindAsEventListener(this));
		
		$('memPlus').observe(Mojo.Event.tap, this.onMemPlusPress.bindAsEventListener(this));
		$('memRecall').observe(Mojo.Event.tap, this.onMemRecallPress.bindAsEventListener(this));
		$('memClear').observe(Mojo.Event.tap, this.onMemClearPress.bindAsEventListener(this));
	},
	
	setResultsDisplayLength: function(len) {
		var resultsDiv = $('resultsText');
		resultsDiv.writeAttribute('size', len);
		resultsDiv.writeAttribute('maxlength', len);
		this.calculator.setMaxDigits(len);
	},
	
	updateResults: function() {
		$('resultsText').setValue(this.calculator.results());
	},
	
	keyMap: $H({
		'0': Mojo.Char.zero,
		'1': Mojo.Char.one,
		'2': Mojo.Char.two,
		'3': Mojo.Char.three,
		'4': Mojo.Char.four,
		'5': Mojo.Char.five,
		'6': Mojo.Char.six,
		'7': Mojo.Char.seven,
		'8': Mojo.Char.eight,
		'9': Mojo.Char.nine,
		'.': Mojo.Char.decimalPoint,
		'+': Mojo.Char.add,
		'-': Mojo.Char.subtract,
		"_": Mojo.Char.subtract,
		'*': Mojo.Char.multiply,
		'/': Mojo.Char.divide,
		'@': Mojo.Char.zero,
		'e': Mojo.Char.one,
		'r': Mojo.Char.two,
		't': Mojo.Char.three,
		'd': Mojo.Char.four,
		'f': Mojo.Char.five,
		'g': Mojo.Char.six,
		'x': Mojo.Char.seven,
		'c': Mojo.Char.eight,
		'v': Mojo.Char.nine,
		'w': Mojo.Char.add,
		's': Mojo.Char.subtract,
		'z': Mojo.Char.multiply,
		'q': Mojo.Char.divide,
		'p': Mojo.Char.enter
	}),

	onKeyPress: function(event) {
		if (Mojo.Char.isEnterKey(event.charCode)) {
			this.onEqualsPress(event);
		} else if (event.charCode == Mojo.Char.backspace) {
			this.onBackspacePress(event);
		} else if (event.charCode == Mojo.Char.spaceBar) {
			this.toggleOptionKeyMode();
		} else {
			var key = this.keyMap.get(String.fromCharCode(event.charCode).toLowerCase());
			if (key) {
				if (Mojo.Char.isDigit(key)) {
					this.onNumberPress(event, key - Mojo.Char.zero);
					return;
				}
				switch (key) {
					case Mojo.Char.decimalPoint:
						this.onDecimalPress(event);
						break;
					case Mojo.Char.add:
						if (!this.optionKeys)
							this.onAddPress(event);
						break;
					case Mojo.Char.subtract:
						if (!this.optionKeys)
							this.onSubtractPress(event);
						break;
					case Mojo.Char.multiply:
						if (!this.optionKeys)
							this.onMultiplyPress(event);
						break;
					case Mojo.Char.divide:
						if (!this.optionKeys)
							this.onDividePress(event);
						break;
					case Mojo.Char.backspace:
						this.onBackspacePress(event);
						break;
					case Mojo.Char.enter:
						this.onEqualsPress(event);
						break;
					case Mojo.Char.opt:
						this.toggleOptionKeyMode();
						break;
				}
			}
		}
	},
  
  	clearOperatorHighlight: function() {
		$('divide').removeClassName('operator');
		$('multiply').removeClassName('operator');
		$('subtract').removeClassName('operator');
		$('add').removeClassName('operator');	
	},
  
 	onKeyDown: function(keyDownEvent) {
		if (keyDownEvent.keyCode == Mojo.Char.enter) {
			this.onEqualsPress(event);
		}
	},

 	onNumberPress: function(event, number) {
		this.clearOperatorHighlight();
		this.calculator.enterDigit(number);
		this.updateResults();
		event.stop();
	},
	
  	onDecimalPress: function(event) {
		this.clearOperatorHighlight();
		this.calculator.enterDecimal();
		this.updateResults();
		event.stop();
	},
	
  	onDividePress: function(event) {
		this.clearOperatorHighlight();
		if (this.optionKeys) {
			this.calculator.memMinus();
			this.showMemoryIndicator();
			this.toggleOptionKeyMode();
		} else {
			$('divide').addClassName('operator');
			this.calculator.divide();
		}
		this.updateResults();
		event.stop();
	},
	
  	onMultiplyPress: function(event) {
		this.clearOperatorHighlight();
		if (this.optionKeys) {
			this.calculator.percent();
			this.toggleOptionKeyMode();
		} else {
			$('multiply').addClassName('operator');
			this.calculator.multiply();
		}
		this.updateResults();
		event.stop();
	},
	
  	onSubtractPress: function(event) {
		this.clearOperatorHighlight();
		if (this.optionKeys) {
			this.calculator.sqrt();
			this.toggleOptionKeyMode();
		} else {
			$('subtract').addClassName('operator');
			this.calculator.subtract();
		}
		this.updateResults();
		event.stop();
	},
	
  	onAddPress: function(event) {
		this.clearOperatorHighlight();
		if (this.optionKeys) {
			this.calculator.plusMinus();
			this.toggleOptionKeyMode();
		} else {
			$('add').addClassName('operator');
			this.calculator.add();
		}
		this.updateResults();
		event.stop();
	},
	
  	onEqualsPress: function(event) {   
		this.clearOperatorHighlight();
		this.calculator.equals();
		this.updateResults();
		event.stop();
	},
	
  	onClearPress: function(event) {
		this.clearOperatorHighlight();
		this.calculator.clear();
		this.updateResults();
		event.stop();
	},
	
  	onMemPlusPress: function(event) {
		this.calculator.memPlus();
		this.showMemoryIndicator();
		this.updateResults();
		event.stop();
	},
	
  	onMemRecallPress: function(event) {
		this.clearOperatorHighlight();
		this.calculator.memRecall();
		this.updateResults();
		event.stop();
	},
	
	onBackspacePress: function(event) {
		this.calculator.backspace();
		this.updateResults();
		event.stop();
	},
	
  	onMemClearPress: function(event) {
		this.calculator.memClear();
		this.hideMemoryIndicator();
		this.updateResults();
		event.stop();
	},
	
	showMemoryIndicator: function() {
		$('memory').update('M');
	},
	
	hideMemoryIndicator: function() {
		$('memory').update('');
	},
	
	toggleOptionKeyMode: function() {
		this.clearOperatorHighlight();
		this.optionKeys = !this.optionKeys;
		if (this.optionKeys)
			this.showOptionKeys();
		else
			this.hideOptionKeys();
	},
	
	showOptionKeys: function() {
		$('divide').down().addClassName('option');
		$('multiply').down().addClassName('option');
		$('subtract').down().addClassName('option');
		$('add').down().addClassName('option');
	},
	
	hideOptionKeys: function() {
		$('divide').down().removeClassName('option');
		$('multiply').down().removeClassName('option');
		$('subtract').down().removeClassName('option');
		$('add').down().removeClassName('option');
	},
	
	handleCommand: function(event){
		if (event.type == Mojo.Event.command && event.command == Mojo.Menu.helpCmd) {
			this.controller.serviceRequest("palm://com.palm.applicationManager", {
			  method: "open",
			  parameters: {
			      id: 'com.palm.app.help',
			      params: {
			          target: "http://help.palm.com/calculator/index.html"
			      }
			  }
			});
		} else if (event.type == Mojo.Event.commandEnable && event.command == Mojo.Menu.helpCmd) {
			event.stopPropagation();
		}
	},
});


