/**
 * @name mojo_widget_integerpicker.js
 * @fileOverview This file has functions related to the integer picker widget 
 * which is used to select an integer value for a property between a small number 
 * of choices;
 * See {@link Mojo.Widget.Integer} for more info.

Copyright 2009 Palm, Inc.  All rights reserved.

*/

/**
 * 
 * The integer picker widget is used to select an integer value from fixed range of values.
 * This widget is declared in the scene HTML like this:
 * 
 * 		<div id="integerDiv" x-mojo-element="IntegerPicker" ></div>
 * 
 * In your assistant you set the model using:
 * 
 * 		this.controller.setupWidget('integerDiv', attributes, model);
 * 
 * The widget takes a set of attributes including the property name and set of
 * choices and a model declaring which option is currently active.
 * 
 * 		attributes = {
 * 			property:   propertyName,
 * 						// Determines which model property is used for the widget's 
 * 						// value.  Defaults to 'value' if not specified.
 * 			minValue: 	optional minimum integer value allowed.  Default is 0.
 * 			maxValue:	optional maximum integer value allowed.  Default is 9999.
 * 		}
 * 
 * 		model = {
 * 			value : integerValue   // Current value of widget.
 * 			                       May alternatively be the property named by
 * 			                       the 'property' field in the attributes hash.
 * 			}
 * 
 * ## Handling Click & Change events: ##
 * This widget only supports a change event. 
 * To listen to a change event call
 * 
 * 		$('integerDiv').observe(Mojo.Event.proeprtyChange, this.callback);
 * 
 */
Mojo.Widget.IntegerPicker = Class.create({
  	initialize: function() {
		this.mode = Mojo.Widget.IntegerPicker.PICK_NONE;
  	},
  
  	setup: function() {
		// Which model property to use for our value?
		this.valueName = this.controller.attributes.property || 'value';
	
		this.renderWidget();
  	},
  
	getTemplatePath: function(templateDir) {
		// TODO When added to the frame uncomment 
		//return Mojo.Widget.getSystemTemplatePath(templateDir);
		return "../../../com.palm.app.calendar/app/views/" + templateDir;
	},
  
  	renderWidget: function() {
		var target = this.controller.element;
		var content = Mojo.View.render({object: {integer: this.controller.model.value}, 
										template: this.getTemplatePath("datetime/integerPicker"),
									   });
		target.insert(content);
		var picker = target.childElements()[0];	
		picker.palmPicker = this;					// TODO wich property name to use?

	    this.pickerClickHandler = this.handleClick.bindAsEventListener(this);
		picker.observe('click', this.pickerClickHandler);
	    this.docClickHandler = this.handleDocClick.bindAsEventListener(this);
		
		this.integerTarget = target.select('div#ip_integer_items')[0];
		this.integerPopup = new IntegerPopup(this.controller, this.integerTarget, 'ip-integer', 'ip-integer-open',
										this.integerNavNext.bind(this), 
										this.integerCallback.bind(this), 
										this.integerModeCallback.bind(this), 
										null,
										{min: this.controller.attributes.minValue,
										 max: this.controller.attributes.maxValue,
										 integerItem: this.controller.model.value,
										});
											
	    this.row = this.integerTarget.parentNode.parentNode;
  	},

	handleClick: function(e){
		var id = e.target.identify();
		if ((id == 'ip_integer') || (id == 'ip_integer_items')) {
			this.setPickMode(Mojo.Widget.IntegerPicker.PICK_INTEGER);
		} else {
			if (!this.row.hasClassName('focus')) 
				this.setPickMode(Mojo.Widget.IntegerPicker.PICK_INTEGER);
			else {
				if (!this.integerPopup.snapping && !this.integerPopup.flicking)
					this.setPickMode(Mojo.Widget.IntegerPicker.PICK_NONE);
			}
		}
		Event.stop(e);
	},
	
	handleDocClick: function(e){
		if (!this.integerPopup.snapping && !this.integerPopup.flicking)
			this.setPickMode(Mojo.Widget.IntegerPicker.PICK_NONE);
	},
	
	setActive: function() {
		if (!this.row.hasClassName('focus')) {
			var allPickers = Selector.findChildElements(this.controller.element.ownerDocument, ['div.palm-picker']);
			for (var i = 0; i < allPickers.length; i++) {
				allPickers[i].palmPicker.setPickMode(Mojo.Widget.IntegerPicker.PICK_NONE);
			}
		  	this.row.addClassName('focus');
			Element.observe(this.controller.element.ownerDocument, 'click', this.docClickHandler);
		}
	},

	setInactive: function() {
		if (this.row.hasClassName('focus')) {
		  	this.row.removeClassName('focus');
			Element.stopObserving(this.controller.element.ownerDocument, 'click', this.docClickHandler);
		}
	},

	setPickMode: function(mode) {
		switch (mode) {
			case Mojo.Widget.IntegerPicker.PICK_NONE:
				this.integerPopup.setNoneMode();
				this.setInactive();
				break;
			case Mojo.Widget.IntegerPicker.PICK_INTEGER:
				this.setActive();
				this.integerPopup.setPickMode();
				break;
		}
		this.mode = mode;
	},

	integerNavNext: function() {
	},
	
	integerCallback: function(integer) {
		var oldValue = this.controller.model[this.valueName];
		if (integer == oldValue) {
			return;
		}
		
		// save value:
		this.controller.model[this.valueName] = integer;
		
		// send change event
		Mojo.Event.send(this.controller.element, Mojo.Event.propertyChange,
			{ property: this.valueName,
				value: integer,
				model: this.controller.model
			});
	},	
	
	integerModeCallback: function(mode) {
		if (mode == IntegerPopup.MODE_PICK) {
			this.mode = Mojo.Widget.IntegerPicker.PICK_INTEGER;
		}
	},
  
  	handleModelChanged: function(what, model) {
		var newValue = this.controller.model[this.valueName];
		if ((newValue >= this.controller.attributes.minValue) &&
			(newValue <= this.controller.attributes.maxValue)) 
		{
			this.integerPopup.setInteger(newValue);
		}
  	},
});

Mojo.Widget.IntegerPicker.PICK_NONE = 0;
Mojo.Widget.IntegerPicker.PICK_INTEGER = 1;
