﻿
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
*  Copyright 2008 Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*
* $DateTime: 2008/04/10 13:35:00 $
*
* Adobe Output Module 2.0
*
* MediaGallery Originally Written by Quality Process Incorporated, Enhanced by
* Adobe System China. Contact Sheet written by Adobe System China.
* 
*
**************************************************************************/

AOM.CustomSlider = function(slider) {
	this.initialize(slider);
}

AOM.CustomSlider.prototype.initialize = function(slider) {
	if (slider == undefined)  {
		return false;
	}

	//add slider method
	slider.getValueByIndLocation = function(indLocation) {
		var value = (indLocation *( this.minvalue - this.maxvalue ) + ( this.firstIndLocationValue * this.maxvalue - this.lastIndLocationValue * this.minvalue ) ) 
							/ ( this.firstIndLocationValue - this.lastIndLocationValue );
		return value;
	} 

	slider.getIndLocationByValue = function(value) {
		var indLocation = ( (this.firstIndLocationValue - this.lastIndLocationValue) / (this.minvalue - this.maxvalue) ) 
									* (value - ( (this.firstIndLocationValue * this.maxvalue - this.lastIndLocationValue * this.minvalue) / (this.firstIndLocationValue - this.lastIndLocationValue) ) );	
		return indLocation;
	}

	slider.getFormatText = function(value) {
		if (this.precise == undefined) {
			return value;
		} else {
			return value.toFixed(this.precise);
		}
	}

	slider.recalculate = function() {
		var slider = this;
		if (slider.minvalue == undefined) {
			slider.minvalue = 0;
		} else {
			slider.minvalue = parseFloat(slider.minvalue);
		}
		if (slider.maxvalue == undefined) {
			slider.maxvalue = 1;
		} else {
			slider.maxvalue = parseFloat(slider.maxvalue);
		}
		if (slider.stepdelta != undefined) {
			slider.stepdelta = parseFloat(slider.stepdelta);
			slider.precise = AOM.CustomSlider.getPrecise(slider.stepdelta);
		}
		slider.size = slider.preferredSize;
		slider.hasVSlider = (slider.size.width < slider.size.height) ? true : false;
		slider.sliderSizeValue = slider.size.width;
		slider.indicatorSizeValue = 9;
		slider.firstIndLocationValue = 2;
		slider.lastIndLocationValue = slider.sliderSizeValue - 1 - slider.indicatorSizeValue;
		if (slider.value == undefined) {
			slider.value = slider.minvalue;
			slider.indicatorLocationValue = 2;
		} else {
			slider.value = parseFloat(slider.value);
			slider.indicatorLocationValue = slider.getIndLocationByValue(slider.value);
		}
	}

	//init all values
	slider.recalculate();
	
	//add mouse event listener
	slider.mouseDown = false;
	slider.addEventListener ('mousedown', AOM.CustomSlider.doDown, false);
	slider.addEventListener ('mouseup', AOM.CustomSlider.doUp, false);
	slider.addEventListener('mousemove', AOM.CustomSlider.doMove, false);
	slider.addEventListener('mouseout', AOM.CustomSlider.doOut, false);
	slider.addEventListener('mouseover', AOM.CustomSlider.doOver, false);
	
	return true;
}


AOM.CustomSlider.getPrecise = function(n) {
	var precise = 0;
	var matches = n.toString().match(/^[-+]?[0-9]+(\.[0-9]+)?$/);
	if (matches) {
		if (matches[1] == undefined) {
			precise = 0;
		} else {
			precise = matches[1].length - 1;
		}
	} 

	return precise;
}


AOM.CustomSlider.getClientValue = function(mouseEvent, hasVSlider) {
	if (hasVSlider) {
		return mouseEvent.clientY;
	} else {
		return mouseEvent.clientX;
	}
}


AOM.CustomSlider.doDown = function(event) {
	var slider = event.target;
	
	slider.mouseDown = true;
	var mouseClientValue = AOM.CustomSlider.getClientValue(event, slider.hasVSlider);
	var indicatorLocationValue = slider.indicatorLocationValue;
	
	//if mouse before indicator .
	var value, stepValue;
	if (mouseClientValue < slider.indicatorLocationValue) {
		indicatorLocationValue = mouseClientValue - 4;
		
		if (slider.stepdelta == undefined) {
			if (indicatorLocationValue < slider.firstIndLocationValue) {
				indicatorLocationValue = slider.firstIndLocationValue;
			}

			slider.indicatorLocationValue = indicatorLocationValue;
			slider.value = slider.getValueByIndLocation(indicatorLocationValue);
		} else {
			value = slider.getValueByIndLocation(indicatorLocationValue);
			stepValue = Math.floor((value - slider.minvalue)/slider.stepdelta + 0.5) * slider.stepdelta + slider.minvalue;
		
			if (stepValue < slider.minvalue) stepValue = slider.minvalue;
			slider.value = stepValue;
			slider.indicatorLocationValue = slider.getIndLocationByValue(slider.value);
		}
	}

	//if mouse after
	if ( mouseClientValue > (slider.indicatorLocationValue + slider.indicatorSizeValue) ) {
		indicatorLocationValue = mouseClientValue - 4;
		
		if (slider.stepdelta == undefined) {
			if (indicatorLocationValue > slider.lastIndLocationValue) {
				indicatorLocationValue = slider.lastIndLocationValue;
			}
		
			slider.indicatorLocationValue = indicatorLocationValue;
			slider.value = slider.getValueByIndLocation(indicatorLocationValue);
		} else {
			value = slider.getValueByIndLocation(indicatorLocationValue);
			stepValue = Math.floor((value - slider.minvalue)/slider.stepdelta + 0.5) * slider.stepdelta + slider.minvalue;
		
			if (stepValue > slider.maxvalue) stepValue = slider.maxvalue;
		
			slider.value = stepValue;
			slider.indicatorLocationValue = slider.getIndLocationByValue(slider.value);
		}
	}
	
	//store current value
	slider.oldMouseClientValue = mouseClientValue;
	slider.oldIndicatorLocationValue = slider.indicatorLocationValue;
	
	slider.notify("onDraw");
	//manual call onChange event
	
	slider.onChange();
}


AOM.CustomSlider.doMove = function(event) {
	var slider = event.target;
	
	//TODO, work around, to fix a bug: when mouse move out the application,  the mouse out event can't be triggered.
	if (event.clientX == 0 && event.clientY == 0) {
		slider.mouseDown = false;
	}

	if (slider.mouseDown == false 
		|| (slider.oldMouseClientValue == undefined || slider.oldIndicatorLocationValue == undefined))  return;
		
	var mouseClientValue = AOM.CustomSlider.getClientValue(event, slider.hasVSlider);
	var oldMouseClientValue = slider.oldMouseClientValue;
	var oldIndicatorLocationValue = slider.oldIndicatorLocationValue;
	
	var indicatorLocationValue ;
	var value, stepValue;
	if (mouseClientValue > oldMouseClientValue) {
		//move down
		indicatorLocationValue = oldIndicatorLocationValue + (mouseClientValue - oldMouseClientValue);
		
		if (slider.stepdelta == undefined) {
			if (indicatorLocationValue > slider.lastIndLocationValue) {
				indicatorLocationValue = slider.lastIndLocationValue;
			}

			slider.indicatorLocationValue = indicatorLocationValue;
			slider.value = slider.getValueByIndLocation(indicatorLocationValue);
		} else {
			value = slider.getValueByIndLocation(indicatorLocationValue);
			stepValue = Math.floor((value - slider.minvalue)/slider.stepdelta + 0.5) * slider.stepdelta + slider.minvalue;
		
			if (stepValue > slider.maxvalue) stepValue = slider.maxvalue;
		
			slider.value = stepValue;
			slider.indicatorLocationValue = slider.getIndLocationByValue(slider.value);
		}
	} else {
		//move up
		indicatorLocationValue = oldIndicatorLocationValue +  (mouseClientValue - oldMouseClientValue);
		
		if (slider.stepdelta == undefined) {
			if (indicatorLocationValue < slider.firstIndLocationValue) {
				indicatorLocationValue = slider.firstIndLocationValue;
			}
		
			slider.indicatorLocationValue = indicatorLocationValue;
			slider.value = slider.getValueByIndLocation(indicatorLocationValue);
		} else {
			value = slider.getValueByIndLocation(indicatorLocationValue);
			stepValue = Math.floor((value - slider.minvalue)/slider.stepdelta + 0.5) * slider.stepdelta + slider.minvalue;
		
			if (stepValue < slider.minvalue) stepValue = slider.minvalue;
			slider.value = stepValue;
			slider.indicatorLocationValue = slider.getIndLocationByValue(slider.value);
		}
	}

	slider.notify("onDraw");
	
	//manual call onChange event
	slider.onChange();
}

AOM.CustomSlider.doOver = function(event) {
	//
}

AOM.CustomSlider.doUp = function(event) {
	var slider = event.target;
	slider.mouseDown = false;
}

AOM.CustomSlider.doOut= function(event) {
	var slider = event.target;
	slider.mouseDown = false;
}


//////////////////////////////////////////////////////////////////////////////////////////////Create NumericStepper class

AOM.AmgNumericStepper = function() {
	this.numericStepperGroup = undefined;
	this.width = undefined;
	this.value = undefined;
	this.onChange = function() {};
}

AOM.AmgNumericStepper.PROP_TEXT = "text";
AOM.AmgNumericStepper.PROP_MINVALUE = "minvalue";
AOM.AmgNumericStepper.PROP_MAXVALUE = "maxvalue";
AOM.AmgNumericStepper.PROP_VALUE = "value";
AOM.AmgNumericStepper.PROP_STEPDELTA = "stepdelta";
AOM.AmgNumericStepper.PROP_PREFERREDSIZE = "preferredSize";
AOM.AmgNumericStepper.MIN_SLIDER_WIDTH = 50;

AOM.AmgNumericStepper.prototype.createControl= function(group) {
	//default 
	var numericStepperGroup= group.add(AOM.AmgNumericStepper.mainResource);
	this.numericStepperGroup = numericStepperGroup;
	this.initialize();
	
	return numericStepperGroup;
}

AOM.AmgNumericStepper.prototype.initialize = function() {
	//init custom slider bar
	var amgNumericStepperObj = this;
	var customSlider = new AOM.CustomSlider(this.getControl("slider"));

	var slider = this.getControl("slider");
	var et = this.getControl("edittext");
		
	//init event -handler
	slider.onChange = function() {
		et.text = this.getFormatText(this.value);
		
		amgNumericStepperObj.value = this.value;		
		if (amgNumericStepperObj.oldValue == undefined) {
			amgNumericStepperObj.oldValue = amgNumericStepperObj.value;
			amgNumericStepperObj.onChange();
		} else {
			if (amgNumericStepperObj.oldValue != amgNumericStepperObj.value) {
				amgNumericStepperObj.oldValue = amgNumericStepperObj.value;
				amgNumericStepperObj.onChange();
			}
		}
	}

	et.onChange = function() {
		//trim value	
		var text = this.text.replace(/^\s+|\s+$/g, '');
		
		//check number
		var matches = text.match(/^([-+]?[0-9]+(\.[0-9]+)?)([^\d])*$/);
		var value;
		if (matches) {
			value = parseFloat(matches[1]);
		} else {
			value= slider.value;
		}
	
		//check range
		if (value > slider.maxvalue) value = slider.maxvalue;
		if (value < slider.minvalue) value = slider.minvalue;
		
		//if stepdelta, jump value
		if (slider.stepdelta != undefined) {
			var stepValue = Math.floor((value - slider.minvalue)/slider.stepdelta + 0.5) * slider.stepdelta + slider.minvalue;
			value = stepValue;
		}
	
		//output has formated text
		this.text = slider.getFormatText(value);
		
		//manual call slider
		slider.value = value;
		slider.indicatorLocationValue = slider.getIndLocationByValue(value);
		
		amgNumericStepperObj.value = value;		
		if (amgNumericStepperObj.oldValue == undefined) {
			amgNumericStepperObj.oldValue = amgNumericStepperObj.value;
			amgNumericStepperObj.onChange();
		} else {
			if (amgNumericStepperObj.oldValue != amgNumericStepperObj.value) {
				amgNumericStepperObj.oldValue = amgNumericStepperObj.value;
				amgNumericStepperObj.onChange();
			}
		}
		
		//slider.notify("onDraw");
	}
	et.addEventListener('keydown', AOM.CS.Keyboards.rowAndColumnEditKeyBoardHandler);
	//init edittext
	et.text = slider.getFormatText(slider.value);
}

AOM.AmgNumericStepper.prototype.setValue = function(value) {
	var slider = this.getControl("slider");
	var et = this.getControl("edittext");
	
	this.value = value;
	this.oldValue = value;
	slider.value = this.value;
	slider.recalculate();
	et.text = slider.getFormatText(this.value);
}

/* AMG 2.0 not yet uses this label.
AOM.AmgNumericStepper.prototype.setHeadLabel = function(props) {
	if (props != undefined && props instanceof Object) {
		var headLabel = this.getControl("headLabel");
		
		if (props[AOM.AmgNumericStepper.PROP_TEXT] != undefined) {
			headLabel.text = props[AOM.AmgNumericStepper.PROP_TEXT];
		}
	
		if (props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] != undefined) {
			headLabel.preferredSize = props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] ;
		}
	} 
} */

AOM.AmgNumericStepper.prototype.setFootLabel = function(props) {
	if (props != undefined && props instanceof Object) {
		var footLabel = this.getControl("footLabel");
		
		if (props[AOM.AmgNumericStepper.PROP_TEXT] != undefined) {
			footLabel.text = props[AOM.AmgNumericStepper.PROP_TEXT];
		}
	
		if (props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] != undefined) {
			footLabel.preferredSize = props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] ;
		}
	
	} 
}

AOM.AmgNumericStepper.prototype.setEditText= function(props) {
	if (props != undefined && props instanceof Object) {
		var et = this.getControl("edittext");
		
		if (props[AOM.AmgNumericStepper.PROP_TEXT] != undefined) {
			et.text = props[AOM.AmgNumericStepper.PROP_TEXT];
		}
	
		if (props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] != undefined) {
			et.preferredSize = props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] ;
		}
	} 
} 

AOM.AmgNumericStepper.prototype.setSlider = function(props) {
	if (props != undefined && props instanceof Object) {
		var slider = this.getControl("slider");
		var et = this.getControl("edittext");
		
		if (props[AOM.AmgNumericStepper.PROP_MINVALUE] != undefined) {
			slider.minvalue = props[AOM.AmgNumericStepper.PROP_MINVALUE];
		}
		if (props[AOM.AmgNumericStepper.PROP_MAXVALUE] != undefined) {
			slider.maxvalue = props[AOM.AmgNumericStepper.PROP_MAXVALUE];
		}
		if (props[AOM.AmgNumericStepper.PROP_STEPDELTA] != undefined) {
			slider.stepdelta = props[AOM.AmgNumericStepper.PROP_STEPDELTA];
		}
		if (props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] != undefined) {
			slider.preferredSize = props[AOM.AmgNumericStepper.PROP_PREFERREDSIZE] ;
		}
		if ( this.value != undefined) {
			slider.value = this.value;
		}
	
		slider.recalculate();
		et.text = slider.getFormatText(slider.value);
	}
}

AOM.AmgNumericStepper.prototype.getControl = function(name) {
	if (name == undefined) return undefined;
	
	var control;
	switch(name) {
		case "edittext" :
			control = this.numericStepperGroup.footGroup.et;
			break;
		case "slider" :
			control = this.numericStepperGroup.sld;
			break;
		// case "headLabel" :
		//	control = this.numericStepperGroup.headLabel;
		//	break;
		case "footLabel" :
			control = this.numericStepperGroup.footGroup.footLabel;
			break;
		default :
			control = undefined;
			break;
	}

	return control;
}

AOM.AmgNumericStepper.mainResource = 
"group {\
	orientation: 'row', \
	alignment:['right', 'top'], alignChildren:['left', 'top'], spacing:12, margins:0, \
	sld:Custom{type:'customBoundedValue', themeType:'numericstepper', preferredSize:[50, 20], minvalue: 0, maxvalue:1},\
	footGroup: Group{\
		spacing: 3, \
		et:EditText{text:'', preferredSize:[25, 20],properties:{borderless:true}},\
		footLabel:StaticText{text:'', preferredSize:[20, 20]}\
	}\
}";
