
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
*  Copyright 2011 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: $
*
* Adobe Output Module 4.0
*
* MediaGallery Originally Written by Quality Process Incorporated, Enhanced by
* Adobe Systems China. Contact Sheet written by Adobe Systems China.
* 
*
**************************************************************************/


/**
 *
 * AOM.Dial implement an angle selection control.
 *
 */
AOM.Dial = function(parentGroup) {
	this.initialize(parentGroup);
}

AOM.Dial.CIRCLE_DIAMETER = 37;

AOM.Dial.prototype.initialize = function(parentGroup) {
	// Create new custom control
	var dial = parentGroup.dial = parentGroup.add(
		"customBoundedValue{\
			themeType:'dial',\
			preferredSize:[" + AOM.Dial.CIRCLE_DIAMETER + ", " + AOM.Dial.CIRCLE_DIAMETER + "],\
			imagePath:'" + AOM.CS.Paths.images + "',\
		}"
	);
	
	this.dial = dial;
		
	// Add event listener
	dial.addEventListener('mousedown', AOM.Dial.onMouseDown, false);
	dial.addEventListener('mouseup', AOM.Dial.onMouseUp, false);
	dial.addEventListener('mousemove', AOM.Dial.onMouseMove, false);
	dial.addEventListener('mouseout', AOM.Dial.onMouseOut, false);
	dial.addEventListener('mouseover', AOM.Dial.onMouseOver, false);
	
	// Init Dial properties
	dial.isMouseDown = false;
	dial.size = dial.preferredSize;
	dial.radius = Math.floor(dial.size.width / 2);
	dial.circlePoint = {x:dial.radius, y:dial.radius};
	dial.point = {x:0, y:0};
	dial.pointerLength = dial.radius - 3;
	
	if (AOM.Dial.CIRCLE_PIXEL_ALPHA_ARRAY == undefined) {
		AOM.Dial.CIRCLE_PIXEL_ALPHA_ARRAY = AOM.Dial.getCirclePixelAlphaArray();
	}
}

AOM.Dial.onMouseUp = function(event) {
	var dial = event.currentTarget;
	if (!dial.enabled) {
		return;
	}
	dial.isMouseDown = false;
}

AOM.Dial.onMouseDown = function(event) {
	var dial = event.currentTarget;
	
	// Workaround: Bring Bridge to the front if it isn't 
	if (dial.gsEnabled != dial.enabled) {
		app.bringToFront();
	}

	if (!dial.enabled) {
		return;
	}
	dial.active = true;
	dial.isMouseDown = true;
	dial.point = AOM.Dial.computePointByMousePos(dial, event.clientX, event.clientY);
	dial.onChange();
    dial.notify("onDraw");
}

AOM.Dial.onMouseMove = function(event) {
	var dial = event.currentTarget;
	if (!dial.enabled) {
		return;
	}
	if (dial.isMouseDown) {
		dial.point = AOM.Dial.computePointByMousePos(dial, event.clientX, event.clientY);
		dial.notify("onDraw");
		dial.onChange();
	}
}

AOM.Dial.onMouseOut = function(event) {
	var dial = event.currentTarget;
	if (!dial.enabled) {
		return;
	}
	dial.isMouseDown = false;
}

AOM.Dial.onMouseOver = function(event) {
	//
}

AOM.Dial.computePointByMousePos = function(dial, clientX, clientY) {
	if (clientX == undefined || clientY == undefined) {
		return undefined;
	}
	var r = dial.radius;
	var pLen = dial.pointerLength;
	var cx = clientX, cy = clientY;
	var x0 = dial.circlePoint.x, y0 = dial.circlePoint.y;
	var dx = cx - x0, dy = cy - y0;
	
	// If user click the center point, set dial angle to zero. 
	if (dx == 0 && dy == 0) {
		return {x:(x0 + pLen), y:y0};
	}

	if (cx >= x0) {
		var x = x0 + pLen * Math.cos(Math.atan((dy / dx)));
		var y = y0 + pLen * Math.sin(Math.atan((dy / dx)));
	} else {
		var x = x0 - pLen * Math.cos(Math.atan((dy / dx)));
		var y = y0 - pLen * Math.sin(Math.atan((dy / dx)));
	}
	return {x:x, y:y};
}

AOM.Dial.getCirclePixelAlphaArray = function() {
	var imagePath = AOM.Paths.project + "/contactsheet/resources/images/dials_circle_line.png";
	var btmap = new BitmapData(File(imagePath));
	var circlePixelAlphaArray = new Array();
	var color;
	
	for (var i = 0; i < AOM.Dial.CIRCLE_DIAMETER; ++i) {
		var row = new Array();
		for (var j = 0; j < AOM.Dial.CIRCLE_DIAMETER; ++j) {
			color = new Color(btmap.getPixel32(i, j));
			row[j] = color.alpha;
		}
		circlePixelAlphaArray[i] = row;
	}

	return circlePixelAlphaArray;
}

AOM.Dial.prototype.getDialAngle = function() {
	var point = this.getPoint();
	var circlePoint = this.getCirclePoint();
	var dx = point.x - circlePoint.x, dy = point.y - circlePoint.y;
	var dialAngle;

	if (dx >= 0) {
		dialAngle = Math.atan(dy / dx) * 180 / Math.PI;
	} else {
		if (dy > 0) {
			dialAngle = Math.atan(dy / dx) * 180 / Math.PI + 180;
		} else {
			dialAngle = Math.atan(dy / dx) * 180 / Math.PI - 180;
		}
	}
	return dialAngle;
}

AOM.Dial.prototype.redraw = function() {
	this.dial.notify("onDraw");
}

AOM.Dial.prototype.setPoint = function(point) {
	this.dial.point = point;
}

AOM.Dial.prototype.getPoint = function() {
	return this.dial.point;
}

AOM.Dial.prototype.getRadius = function() {
	return this.dial.radius;
}

AOM.Dial.prototype.getPointerLength = function() {
	return this.dial.pointerLength;
}

AOM.Dial.prototype.getCirclePoint = function() {
	return this.dial.circlePoint;
}

AOM.Dial.prototype.setDialOnChange = function(callback) {
	this.dial.onChange = callback;
}

///////////////////////////////////////////////////////////////////////////////////

/**
 *
 * AOM.DialGroup
 *
 */
AOM.DialGroup = function(parentGroup) {
	this.initialize(parentGroup);
}

AOM.DialGroup.angleToPoint = function(etAngle, dialObj) {
	var circlePoint = dialObj.getCirclePoint();
	var pLen = dialObj.getPointerLength();
	var dialAngle = -etAngle / 180 * Math.PI;
	var x0 = circlePoint.x, y0 = circlePoint.y;
	var dialX = x0 + pLen * Math.cos(dialAngle);
	var dialY = y0 + pLen * Math.sin(dialAngle);
	
	return {x:dialX, y:dialY};
}

AOM.DialGroup.pointToAngle = function(dialObj) {
	var dialAngle = dialObj.getDialAngle();

	// Change dialAngle to etAngel
	var etAngle = -dialAngle;
	return Math.round(etAngle);
}

AOM.DialGroup.prototype.getValue = function() {
	return this.editText.text;
}

AOM.DialGroup.prototype.setValue = function(angleValue) {
	if (angleValue == undefined || angleValue == "undefined" || angleValue.length == 0) {
		return;
	}
	this.editText.text = angleValue;
	this.dialObj.setPoint(AOM.DialGroup.angleToPoint(angleValue, this.dialObj));
	this.dialObj.redraw();
}

AOM.DialGroup.prototype.getName = function() {
	return this.name;
}

AOM.DialGroup.prototype.initialize = function(parentGroup) {
	// Add maingroup
	this.mainGroup = parentGroup.add("Group");
	this.mainGroup.alignChildren = parentGroup.alignChildren;
	this.mainGroup.spacing = parentGroup.spacing;
	this.name = parentGroup.name;

	// Add label
	var labelTitle = parentGroup.title;
	if (labelTitle == undefined) {
		labelTitle = "";
	}
	this.label = this.mainGroup.add("StaticText");
    this.label.text = labelTitle;
    this.label.preferredSize = [-1, 18];
	
	// Add Dial
	this.dialObj = new AOM.Dial(this.mainGroup);
	
	// Add edit-text
	var etSize = parentGroup.editTextSize;
	if (etSize == undefined) {
		etSize = [35, 18];
	}
	var etGroup = this.mainGroup.add(
	"group{\
		alignChildren:['right', 'center'], spacing:3,\
		et:EditText{text:'', preferredSize:[" + etSize + "], properties:{borderless:true}},\
		dst:StaticText{text:'\u00b0', preferredSize:[8, 9], alignment:['left', 'top']},\
	}");
	this.editText = etGroup.et; 
	this.editText.addEventListener('keydown', AOM.Keyboard.integerEditText);
	
	// Add event-handlers 
	var dialGroup = this;
	var dialOnChange = function() {
		var etAngle = AOM.DialGroup.pointToAngle(dialGroup.dialObj);
		dialGroup.editText.text = etAngle;
		
		dialGroup.onChange();
	}
	this.dialObj.setDialOnChange(dialOnChange);
	
	this.editText.onChange = function() {
		// Check number
		var text = this.text.replace(/^\s+|\s+$/g, '');
		var matches = text.match(/^([-+]?[0-9]+(\.[0-9]+)?)([^\d])*$/);
		if (matches) {
			var value = parseInt(matches[1]); 
			
			// Check range
			if (value > 360) value = 360;
			if (value < -360) value = -360;
		
			this.text = value;
		
			// Manual call dial
			dialGroup.dialObj.setPoint(AOM.DialGroup.angleToPoint(value, dialGroup.dialObj));
			dialGroup.dialObj.redraw();
		} else {
			this.text = AOM.DialGroup.pointToAngle(dialGroup.dialObj); 
		}
	
		dialGroup.onChange();	
	}

	// Init datas
	var defaultValue = parentGroup.defaultValue;
	if (defaultValue == undefined) {
		defaultValue = 0;
	}
	this.setValue(defaultValue);
}

AOM.DialGroup.prototype.onChange = function() {
	//
}

