/*______________
|       ______  |   U I Z E     J A V A S C R I P T     A P I
|     /      /  |   -----------------------------------------
|    /    O /   |    MODULE : Uize.Widget.Dial Class (version 1.0)
|   /    / /    |    AUTHOR : Jan Martin Borgersen
|  /    / /  /| |    ONLINE : http://www.tomkidding.com/uize/uize-js-api
| /____/ /__/_| | COPYRIGHT : (c)2007 Jan Martin Borgersen
|           |__ |   LICENSE : Distributed under the terms of the GNU General Public License
|_______________|             http://www.gnu.org/licenses/gpl.txt
*/

/*
	DESCRIPTION
		Implements an angular, roundish widget.
		The "frames" implied node is a multi image.

	REQUIRES
		- Uize.Widget.js (base class)
		- Uize.Node.js
*/

/*ScruncherSettings Mappings="=c" LineCompacting="TRUE"*/

(function () {
	/*** Variables for Scruncher Optimization ***/
		var
			_true = true,
			_false = false,
			_Uize_Node = Uize.Node,
			_Uize_Widget = Uize.Widget,
			_navigator = navigator,
			_userAgent = _navigator.userAgent.toLowerCase (),
			_isIe = _navigator.appName == 'Microsoft Internet Explorer'
		;

	/*** Object Constructor ***/
		var
			_superclass = _Uize_Widget,
			_class = _superclass.Dial = _superclass.subclass (
				null,
				function () {
					var _this = this;
					_this._choosing = false;
					_this._startingAngle = 0;
				}
			),
			_classPrototype = _class.prototype
		;

	/*** Public Instance Methods ***/

		_classPrototype.updateUi = function () {
			var _this = this
			if (_this.wired()) {
				var
					_this = this,
					_theValue = _this._choosing ? _this._tempValue : _this._value
				;
				_theValue -= _this._minValue;
				_this.getNode('frames').style.top = '-'+(_theValue*_this._height)+'px';
			}
		};

		_classPrototype.wireUi = function () {
			var _this = this;
			if (!_this.wired ()) {
				
				function _getCurrentAngle(_event) {
					var 
						_framesScroll = _Uize_Node.getCoords(_this.getNode('frames')).top - _Uize_Node.getCoords(_this.getNode('')).top,
						_xPosition = Math.floor( (_isIe ? _event.offsetX : _event.layerX) - (_this._width/2) ),
						_yPosition = Math.floor((_this._height/2)-((_isIe ? _event.offsetY : _event.layerY)+_framesScroll)),
						_angle = Math.atan2( _xPosition, _yPosition )
					;
					if( _angle < 0 ) _angle += 2*Math.PI;
					return _angle;
				}

				_this.wireNodeEvent('','onmousedown',function(_event){
					_this._choosing = _true;
					_this._startingAngle = _getCurrentAngle(_event);
					_this.fireEvent('Dialing');
				});
				_this.wireNodeEvent('','onmouseup',function(){
					_this._choosing = _false;
					_this.set({value:_this._tempValue});
					_this.fireEvent('Dialed');
				});
				_this.wireNodeEvent('','onmouseout',function(){
					_this._choosing = _false;
					_this.updateUi();
					_this.fireEvent('Abort');
				});
				_this.wireNodeEvent('','onmousemove',function(_event) {
					if(_this._choosing) {
						var 
							_currentSteps = (_this._value - _this._minValue) / _this._stepSize,
							_angle = _getCurrentAngle(_event) - _this._startingAngle
						;
						if( _angle < 0 ) _angle += 2*Math.PI;
						var _offsetSteps = Math.round(_this._steps * _angle / (2*Math.PI));
						var _newSteps = (_currentSteps + _offsetSteps) % _this._steps;
						_this.set({tempValue:_this._minValue + (_newSteps*_this._stepSize)});
					}
				});
				_superclass.prototype.wireUi.call (_this);
			}
		};
		
/*** Setup Properties ***/
		_class.registerProperties ({
			_tempValue:{
				name:'tempValue',
				value:0,
				onChange:function () {
					this.updateUi();
				}
			},
			_value:{
				name:'value',
				value:0,
				onChange:function () {
					this.updateUi();
				}
			},
			_minValue:{
				name:'minValue',
				value:0
			},
			_steps:{
				name:'steps',
				value:10
			},
			_stepSize:{
				name:'stepSize',
				value:1
			},
			_height:{
				name:'height',
				value:100
			},
			_width:{
				name:'width',
				value:100
			}
		});
}) ();


