/*Copyright (c) 2006-2007, ePages GmbH
	All Rights Reserved.
	epages.cartridges.de_epages.presentation.widget.Colorpicker $Revision: 1.67 $*/

dojo.provide("epages.cartridges.de_epages.presentation.widget.Colorpicker");
dojo.require("epages.widget.LocalizedWidget");
dojo.require("epages.lang.hitch");
dojo.require("epages.lang.color");
dojo.require('epages.event');
dojo.require('epages.validate.css');
dojo.require("epages.widget.Validateinput");
dojo.require("dojo.dnd.Source");
dojo.require("dijit.Dialog");
dojo.require('epages.string');

dojo.declare("epages.cartridges.de_epages.presentation.widget.Colorpicker",
	[epages.widget.LocalizedWidget],
	{
		/**
		 * public properties
		 */
		currentColor        : "",
		userColors          : '',
		FeatureColorOptions : true,
		currentWizardScheme : 'Compound',
		numberOfUserColors  : 20,
		numberOfWizardColors: 5,
		objectId            : '',
		allowEmpty          : '0',          // Boolean - allow empty value
		/**
		 * private properties
		 */
		_isGradientPushed     : false,
		_isSliderPushed       : false,
		_activeCurrentColor   : null,
		_isInSetCurrentColor  : false,
		_noColor              : {r: 255, g: 255, b: 255},
		_assignedInput        : undefined,  // DomNode - target input element of colorpicker
		_allowTransparency    : false,      // Boolean - show or hide transparent color boxes
		_avatar               : undefined,
		_blockAvatar          : false,
		_activeWizardColor    : undefined,
		_unsavedChanges       : undefined,
		_positionGradient     : undefined,
		_positionSlider       : undefined,
		_underlay             : undefined,
		/**
		 * constants
		 */
		COLORSLIDER_IMAGE_HEIGHT: 8,
		COLORPICKER_IMAGE_HEIGHT: 14,
		/**
		 * widget properties
		 */
		templatePath      : dojo.moduleUrl('epages.cartridges.de_epages.presentation.widget', 'templates/Colorpicker.html'),
		translationName   : dojo.moduleUrl('epages.cartridges.de_epages.presentation.widget', 'templates/translation'),
		imagePath         : epages.themeUrl('images'),
		widgetsInTemplate : true,

		postMixInProperties:function(){
			this.inherited("postMixInProperties", arguments);
			this.userColors = epages.vars.StyleUserDefinedColors === undefined ? '' : epages.vars.StyleUserDefinedColors;
			this.FeatureColorOptions = epages.vars.FeatureColorOptions === undefined ? true : epages.vars.FeatureColorOptions;
			this.currentWizardScheme = epages.vars.StyleWizardScheme === undefined || epages.vars.StyleWizardScheme == "" ? 'Compound' : epages.vars.StyleWizardScheme;
			this.objectId = epages.vars.StyleId === undefined ? '' : epages.vars.StyleId;
			this.allowEmpty = epages.string.toBoolean(this.allowEmpty);
		},

		postCreate: function() {
			this.inherited("postCreate", arguments);
			//add underlay
			this._underlay = new dijit.DialogUnderlay();
			dojo.removeClass(this._underlay.node,'dijitDialogUnderlay');
			// create color table with userdefined colors
			var userColors = this.userColors.split("|");
			this.userColors = [];
			for (var i = 0; i < this.numberOfUserColors; i++) {
				var div = document.createElement('div');
				div.className='ColorBox';
				div.setAttribute('id', 'ColorPickerUserColor_' + i);
				div.title = userColors[i];

				var color = i < userColors.length ? epages.lang.color.cssString2Rgb(userColors[i]) : this._noColor;

				if (i == userColors.length){
					color.transparent=1;
					dojo.addClass(div, "ColorBoxTransparent");
				}
				else{
					color.transparent=0;
					div.style.backgroundColor = epages.lang.color.rgb2Hex(color);
					if(this.FeatureColorOptions) {
						//create D'N'D target for every user color
						var dndTarget = new dojo.dnd.Target(div,{});
						dojo.addClass(div, "dropAllowed");
					}
				}

				this.userColorsNode.appendChild(div);
				this.userColors[i] = {
					node:   div,
					color:  color
				};
			}
			if(!this.FeatureColorOptions) {
					this.switchWizard.style.display = 'none';
					this.userColorsNode.style.display = 'none';
					this.colorWizardColorsNode.style.display = 'none';
					this.colorWizardColorsTitleNode.style.display = 'none';
					this.UserDefinedColorsText.style.display = 'none';
					this.curSelectedColor.style.width = '90px';
					this.curSelectedColor.style.marginLeft = '17px';
					dojo.removeClass(this.curSelectedColor,"dojoDndItem");
					dojo.removeClass(this.curSelectedColor,"dragAllowed");
					this.curSelectedColor.style.cursor = "default";
					this.ColorTablesAndInputs.style.width = '109px';
					this.LayerOverIframe.style.width = '448px';
				}

			// create color table for color wizard
			this.wizardColors = [];
			for (var i = 0; i < this.numberOfWizardColors; i++) {
				var div = document.createElement('div');
				div.className='ColorBox';
				div.setAttribute('id', 'ColorPickerWizardColor_' + i);

				this.colorWizardColorsNode.appendChild(div);
				this.wizardColors[i] = {
					node:   div,
					color:  color
				};
				if(this.FeatureColorOptions){
					//create DND Sources only if Feature Color Options is available
				 	var params = {
						accept: [],
						copyOnly: true
					};
					var dndSource = new dojo.dnd.Source(div,params);
					dndSource.insertNodes(null, ["<div class='dragAllowed' style='width:12px; height:12px'></div>"]);
				}
			}

			// create color table for color wizard layer
			//compound
			this.compoundColors = [];
			for (var i = 0; i < this.numberOfWizardColors; i++) {
				var div = document.createElement('div');
				div.className='ColorBoxLarge';
				div.setAttribute('id', 'ColorPickerWizardColor_' + i);
				this.compoundColorWizardNode.appendChild(div);
				this.compoundColors[i] = {
					node:   div,
					color:  color
				};
			}
			//complementary
			this.complementaryColors = [];
			for (var i = 0; i < this.numberOfWizardColors; i++) {
				var div = document.createElement('div');
				div.className='ColorBoxLarge';
				div.setAttribute('id', 'ColorPickerWizardColor_' + i);
				this.complementaryColorWizardNode.appendChild(div);
				this.complementaryColors[i] = {
					node:   div,
					color:  color
				};
			}
			//triad
			this.triadColors = [];
			for (var i = 0; i < this.numberOfWizardColors; i++) {
				var div = document.createElement('div');
				div.className='ColorBoxLarge';
				div.setAttribute('id', 'ColorPickerWizardColor_' + i);
				this.triadColorWizardNode.appendChild(div);
				this.triadColors[i] = {
					node:   div,
					color:  color
				};
			}
			//analogue
			this.analogueColors = [];
			for (var i = 0; i < this.numberOfWizardColors; i++) {
				var div = document.createElement('div');
				div.className='ColorBoxLarge';
				div.setAttribute('id', 'ColorPickerWizardColor_' + i);
				this.analogueColorWizardNode.appendChild(div);
				this.analogueColors[i] = {
					node:   div,
					color:  color
				};
			}

			if(this.currentColor != ""){
				this.setCurrentColor(epages.lang.color.hex2Rgb(this.currentColor));
			}
			if ((this.switchWizard.className == 'ColorPickerTab')&&(this.switchPicker.className == 'ColorPickerTab')){
				this.switchPicker.className = 'ColorPickerTabActive';
			}
			this._appendEvents();
			this._setWizardColors();
		},


		compoundColorWizard: function(baseColor, outPut){
			var baseColorhsb = epages.lang.color.rgb2Hsb(epages.lang.color.cssString2Rgb(baseColor));
			var hsbColor1 = [];
			var hsbColor2 = [];
			var hsbColor3 = [];
			var hsbColor4 = [];

			// set hue
			if(baseColorhsb.h<340){
				hsbColor1.h = hsbColor2.h = baseColorhsb.h+20;
			}else{
				hsbColor1.h =  hsbColor2.h = (baseColorhsb.h+20)-360;
			}
			if(baseColorhsb.h<240){
				hsbColor3.h = baseColorhsb.h+120;
			}else{
				hsbColor3.h = (baseColorhsb.h+120)-360;
			}
			if(baseColorhsb.h<260){
				hsbColor4.h = baseColorhsb.h+100;
			}else{
				hsbColor4.h = (baseColorhsb.h+100)-360;
			}

			// set saturation
			if(baseColorhsb.s>50){
				hsbColor1.s = baseColorhsb.s-40;
			}else{
				hsbColor1.s = baseColorhsb.s+40;
			}
			if(baseColorhsb.s>90){
				hsbColor2.s = hsbColor4.s = baseColorhsb.s-10;
			}else{
				hsbColor2.s = hsbColor4.s = baseColorhsb.s+10;
			}
			if(baseColorhsb.s>35){
				hsbColor3.s = baseColorhsb.s-25;
			}else{
				hsbColor3.s = baseColorhsb.s+25;
			}

			// set brightness
			if(baseColorhsb.b>60){
				hsbColor1.b = baseColorhsb.b-40;
			}else{
				hsbColor1.b = baseColorhsb.b+40;
			}
			if(baseColorhsb.b>80){
				hsbColor2.b = hsbColor4.b = baseColorhsb.b-20;
			}else{
				hsbColor2.b = hsbColor4.b = baseColorhsb.b+20;
			}
			hsbColor3.b = 100;


			// set colors
			outPut[0].color = epages.lang.color.hsb2Rgb(baseColorhsb);
			outPut[1].color = epages.lang.color.hsb2Rgb(hsbColor1);
			outPut[2].color = epages.lang.color.hsb2Rgb(hsbColor2);
			outPut[3].color = epages.lang.color.hsb2Rgb(hsbColor3);
			outPut[4].color = epages.lang.color.hsb2Rgb(hsbColor4);

			for( var i=0,iLength=outPut.length ; i<iLength ; i++ ) {
				var color = outPut[i].color;
					outPut[i].node.style.backgroundColor = epages.lang.color.rgb2Hex(color);
			}
		},


		analogueColorWizard: function(baseColor, outPut){
			var baseColorhsb = epages.lang.color.rgb2Hsb(epages.lang.color.cssString2Rgb(baseColor));
			var hsbColor1 = [];
			var hsbColor2 = [];
			var hsbColor3 = [];
			var hsbColor4 = [];

			hsbColor1.s = hsbColor2.s = hsbColor3.s = hsbColor4.s = baseColorhsb.s;
			hsbColor1.b = hsbColor2.b = hsbColor3.b = hsbColor4.b = baseColorhsb.b;

			if(baseColorhsb.h<340){
				hsbColor1.h = baseColorhsb.h+20;
			}else{
				hsbColor1.h = (baseColorhsb.h+20)-360;
			}
			if(baseColorhsb.h<320){
				hsbColor2.h = baseColorhsb.h+40;
			}else{
				hsbColor2.h = (baseColorhsb.h+40)-360;
			}
			if(baseColorhsb.h>20){
				hsbColor3.h = baseColorhsb.h-20;
			}else{
				hsbColor3.h = baseColorhsb.h+340;
			}
			if(baseColorhsb.h>40){
				hsbColor4.h = baseColorhsb.h-40;
			}else{
				hsbColor4.h = baseColorhsb.h+320;
			}

			// set colors
			outPut[0].color = epages.lang.color.hsb2Rgb(baseColorhsb);
			outPut[1].color = epages.lang.color.hsb2Rgb(hsbColor1);
			outPut[2].color = epages.lang.color.hsb2Rgb(hsbColor2);
			outPut[3].color = epages.lang.color.hsb2Rgb(hsbColor3);
			outPut[4].color = epages.lang.color.hsb2Rgb(hsbColor4);

			for( var i=0,iLength=outPut.length ; i<iLength ; i++ ) {
				var color = outPut[i].color;
					outPut[i].node.style.backgroundColor = epages.lang.color.rgb2Hex(color);
			}
		},

		triadColorWizard: function(baseColor, outPut){
			var baseColorhsb = epages.lang.color.rgb2Hsb(epages.lang.color.cssString2Rgb(baseColor));
			var hsbColor1 = [];
			var hsbColor2 = [];
			var hsbColor3 = [];
			var hsbColor4 = [];

			//monochrom
			hsbColor1.h = baseColorhsb.h;
			if(baseColorhsb.b > 70){
				hsbColor1.b = baseColorhsb.b-30;
			}else{
				hsbColor1.b = baseColorhsb.b+30;
			}
			if(baseColorhsb.s > 20){
				hsbColor1.s = baseColorhsb.s-10;
			}else{
				hsbColor1.s = baseColorhsb.s+10;
			}

			//kontrast
			hsbColor2.b = baseColorhsb.b;
			if(baseColorhsb.h<240){
				hsbColor2.h = baseColorhsb.h+120;
			}else{
				hsbColor2.h = (baseColorhsb.h+120)-360;
			}
			if(baseColorhsb.s > 20){
				hsbColor2.s = baseColorhsb.s-10;
			}else{
				hsbColor2.s = baseColorhsb.s+10;
			}

			//kontrast2
			if(baseColorhsb.b > 70){
				hsbColor3.b = baseColorhsb.b-30;
			}else{
				hsbColor3.b = baseColorhsb.b+30;
			}
			if(baseColorhsb.h<120){
				hsbColor3.h = baseColorhsb.h+240;
			}else{
				hsbColor3.h = baseColorhsb.h-120;
			}
			if(baseColorhsb.s > 20){
				hsbColor3.s = baseColorhsb.s-10;
			}else{
				hsbColor3.s = baseColorhsb.s+10;
			}
			hsbColor4.b = baseColorhsb.b;
			hsbColor4.s = hsbColor3.s;
			hsbColor4.h = hsbColor3.h;


			// set colors
			outPut[0].color = epages.lang.color.hsb2Rgb(baseColorhsb);
			outPut[1].color = epages.lang.color.hsb2Rgb(hsbColor1);
			outPut[2].color = epages.lang.color.hsb2Rgb(hsbColor2);
			outPut[3].color = epages.lang.color.hsb2Rgb(hsbColor3);
			outPut[4].color = epages.lang.color.hsb2Rgb(hsbColor4);

			for( var i=0,iLength=outPut.length ; i<iLength ; i++ ) {
				var color = outPut[i].color;
					outPut[i].node.style.backgroundColor = epages.lang.color.rgb2Hex(color);
			}
		},

		complementaryColorWizard: function(baseColor, outPut){
			var baseColorhsb = epages.lang.color.rgb2Hsb(epages.lang.color.cssString2Rgb(baseColor));
			var hsbColor1 = [];
			var hsbColor2 = [];
			var hsbColor3 = [];
			var hsbColor4 = [];

			// set hue for monochromatic colors
			hsbColor1.h = hsbColor2.h = baseColorhsb.h;
			// set saturation for all colors
			hsbColor1.s = hsbColor2.s = hsbColor3.s = hsbColor4.s = baseColorhsb.s;

			// change brightness for monochromatic colors
			if(baseColorhsb.b>70){
				hsbColor1.b = baseColorhsb.b-15;
				hsbColor2.b = baseColorhsb.b-30;
			}
			else {
				hsbColor1.b = baseColorhsb.b+15;
				hsbColor2.b = baseColorhsb.b+30;
			}

			// change brightness for complimentary colors
			if(((baseColorhsb.b < 20) && (baseColorhsb.s < 20))||(baseColorhsb.s == 0)){
				hsbColor4.b = 100-baseColorhsb.b;
			}else{
				hsbColor4.b = baseColorhsb.b;
			}

			if(baseColorhsb.s == 0){
				hsbColor3.b = 100-hsbColor2.b;
			}else{
				hsbColor3.b = hsbColor2.b;
			}

			// change hue for complementary colors

			//reines hsb wäre:
			//if(baseColorhsb.h<180) hsbColor3.h = hsbColor4.h = baseColorhsb.h+180;
			//else hsbColor3.h = hsbColor4.h = baseColorhsb.h-180;

			//damit es besser zu rgb passt:
			if((baseColorhsb.h>=0) &&(baseColorhsb.h<10)){ 		hsbColor3.h = hsbColor4.h = baseColorhsb.h+140;}
			if((baseColorhsb.h>=10) &&(baseColorhsb.h<25)){ 	hsbColor3.h = hsbColor4.h = baseColorhsb.h+150;}
			if((baseColorhsb.h>=25) &&(baseColorhsb.h<40)){ 	hsbColor3.h = hsbColor4.h = baseColorhsb.h+165;}
			if((baseColorhsb.h>=40) &&(baseColorhsb.h<55)){ 	hsbColor3.h = hsbColor4.h = baseColorhsb.h+185;}
			if((baseColorhsb.h>=55) &&(baseColorhsb.h<120)){ 	hsbColor3.h = hsbColor4.h = baseColorhsb.h+210;}
			if((baseColorhsb.h>=120) &&(baseColorhsb.h<140)){ hsbColor3.h = hsbColor4.h = baseColorhsb.h+220;}
			if((baseColorhsb.h>=140) &&(baseColorhsb.h<170)){ hsbColor3.h = hsbColor4.h = baseColorhsb.h-150;}
			if((baseColorhsb.h>=170) &&(baseColorhsb.h<200)){ hsbColor3.h = hsbColor4.h = baseColorhsb.h-160;}
			if((baseColorhsb.h>=200) &&(baseColorhsb.h<215)){ hsbColor3.h = hsbColor4.h = baseColorhsb.h-170;}
			if((baseColorhsb.h>=215) &&(baseColorhsb.h<235)){ hsbColor3.h = hsbColor4.h = baseColorhsb.h-180;}
			if((baseColorhsb.h>=235) &&(baseColorhsb.h<260)){ hsbColor3.h = hsbColor4.h = baseColorhsb.h-200;}
			if((baseColorhsb.h>=260) &&(baseColorhsb.h<335)){ hsbColor3.h = hsbColor4.h = baseColorhsb.h-210;}
			if((baseColorhsb.h>=335) &&(baseColorhsb.h<=360)){hsbColor3.h = hsbColor4.h = baseColorhsb.h-220;}

			// set colors
			outPut[0].color = epages.lang.color.hsb2Rgb(baseColorhsb);
			outPut[1].color = epages.lang.color.hsb2Rgb(hsbColor1);
			outPut[2].color = epages.lang.color.hsb2Rgb(hsbColor2);
			outPut[3].color = epages.lang.color.hsb2Rgb(hsbColor3);
			outPut[4].color = epages.lang.color.hsb2Rgb(hsbColor4);

			for( var i=0,iLength=outPut.length ; i<iLength ; i++ ) {
				var color = outPut[i].color;
					outPut[i].node.style.backgroundColor = epages.lang.color.rgb2Hex(color);
			}
		},

		show: function(aroundNode) {
		// summary: Show colorpicker widget.

		// fix for dojo Bug http://trac.dojotoolkit.org/ticket/8445
			this.domNode.style.top = '';
		//end of fix
			dijit.popup.open({popup:this,around:aroundNode});
			var popupLeft = parseInt(this.domNode.parentNode.style.left);
			var rightSpace = this.domNode.ownerDocument.getElementsByTagName('body')[0].offsetWidth - (popupLeft + this.domNode.offsetWidth);
			if(rightSpace < 0){
				this.domNode.parentNode.style.left = (popupLeft + rightSpace) +"px";
			}
			var popupTop = parseInt(this.domNode.parentNode.style.top);
			var bottomSpace = this.domNode.ownerDocument.getElementsByTagName('body')[0].offsetHeight - (popupTop + this.domNode.offsetHeight);
			if(bottomSpace < 0){
				this.domNode.parentNode.style.top = (popupTop + bottomSpace) +"px";
			}
			this.hexInputLayerNode.focus();
			this._underlay.show();
			this._setWizardColors();
			this.domNode.parentNode.style.zIndex = epages.zIndex + 2500;
		},

		setColorInput : function(/*DOMObject*/input,/*Boolean*/allowTransparency, /* Boolean? */ allowEmpty) {
		// summary: set current hex color to target input node
		// description: Assigns a target input field to the colorpicker. Furthermore transparent color boxes
		//  are shown or hidden depending on the passed parameter "allowTransparency".
			if(input.value !="" || !allowEmpty) {
				this.setCurrentColor(epages.lang.color.hex2Rgb(input.value));
			} else if(input.value =="") {
				this.hexInputLayerNode.value = "";
			}
			this._assignedInput=input;
			this._allowTransparency=allowTransparency;
			this.allowEmpty = allowEmpty;
			// show/hide transparent color box
			this._hideTransparentColorBoxes(this.userColorsNode.getElementsByTagName('div'));
		},

		hide: function() {
		// summary: Hide colorpicker player.
			dijit.popup.close(this);
			this._underlay.hide();
		},

		/**
		 * private methods
		 */
		_appendEvents: function() {
			this.connect(this.closeColorPicker,'onclick', '_closeColorPicker');
			// gradient events
			this.connect(this.transparentGradientLayer,'onmousedown', '_gradientMouseDown');
			this.connect(this.transparentGradientLayer,'onmouseup', '_gradientMouseUp');
			this.connect(this.transparentGradientLayer,'onmousemove', '_gradientMouseMove');
			this.connect(this.colorpickerLayer,        'onmouseup', '_sliderMouseUp');
			this.connect(this.colorPickerSelectNode,   'onmousedown', '_gradientMouseDown');

			// color slider events
			this.connect(this.transparentSliderLayer,'onmousedown', '_sliderMouseDown');
			this.connect(this.transparentSliderLayer,'onmouseup', '_sliderMouseUp');
			this.connect(this.transparentSliderLayer,'onmousemove', '_sliderMouseMove');
			this.connect(this.colorSliderNode,       'onmouseup', '_sliderMouseUp');

			//underlay events
			this.connect(this._underlay.node,'onmousemove', '_gradientMouseMove');
			this.connect(this._underlay.node,'onmouseup', '_gradientMouseUp');
			this.connect(this._underlay.node,'onmousemove', '_sliderMouseMove');
			this.connect(this._underlay.node,'onmouseup', '_sliderMouseUp');

			//document events
			this.connect(document,'onmousemove', '_gradientMouseMove');
			this.connect(document,'onmouseup', '_gradientMouseUp');
			this.connect(document,'onmousemove', '_sliderMouseMove');
			this.connect(document,'onmouseup', '_sliderMouseUp');
			//stop onselectstart to avoid selection of text in ie
			this.connect(this.colorWizardColorsTitleNode,'onselectstart', dojo, "stopEvent");

			// input events
			this.connect(this.hexInputLayerNode,  'onchange', '_setHexColor');
			this.connect(this.redInputLayerNode,  'onchange', '_setRgbColor');
			this.connect(this.greenInputLayerNode,'onchange', '_setRgbColor');
			this.connect(this.blueInputLayerNode, 'onchange', '_setRgbColor');
			this.connect(this.hueInputLayerNode,  'onchange', '_setHsbColor');
			this.connect(this.satInputLayerNode,  'onchange', '_setHsbColor');
			this.connect(this.lumInputLayerNode,  'onchange', '_setHsbColor');

			// user defined colors
			for( var i=0,iLength=this.userColors.length ; i<iLength ; i++ ) {
				this.connect(this.userColors[i].node, 'onclick', "_onClickUserColor");
			}

			// wizard colors
			for( var i=0,iLength=this.wizardColors.length ; i<iLength ; i++ ) {
				this.connect(this.wizardColors[i].node, 'onclick', "_setWizardColor");
				this.connect(this.wizardColors[i].node, 'onmousedown', "_setActiveWizardColor");
				this.connect(this.wizardColors[i].node, 'onmouseover', '_showAvatar');
				this.connect(this.wizardColors[i].node, 'onmousemove', '_moveAvatar');
				this.connect(this.wizardColors[i].node, 'onmouseout', '_hideAvatar');
			}

			//current selected color
			if(this.FeatureColorOptions){
				this.connect(document.body,         'onclick', '_deactivateUserColors');
				this.connect(this.curSelectedColor, 'onclick', '_onClickCurrentColor');
				this.connect(this.curSelectedColor, 'onmouseover', '_showAvatar');
				this.connect(this.curSelectedColor, 'onmousemove', '_moveAvatar');
				this.connect(this.curSelectedColor, 'onmouseout', '_hideAvatar');
			}

			// buttons
			this.connect(this.applyButtonNode,    'onclick', '_applyColor');
			this.connect(this.switchWizard,       'onclick', '_switchWizard');
			this.connect(this.switchPicker,       'onclick', '_switchPicker');
			this.connect(this.complementaryTitle, 'onclick', epages.lang.hitch(this, this._setWizardScheme, ['Complementary']));
			this.connect(this.compoundTitle,      'onclick', epages.lang.hitch(this, this._setWizardScheme, ['Compound']));
			this.connect(this.triadTitle,         'onclick', epages.lang.hitch(this, this._setWizardScheme, ['Triad']));
			this.connect(this.analogueTitle,      'onclick', epages.lang.hitch(this, this._setWizardScheme, ['Analogue']));

			//dnd events
			if(this.FeatureColorOptions){
				dojo.subscribe("/dnd/drop",  this,'_onDndDrop');
				dojo.subscribe("/dnd/start", this,'_onDndStart');
				dojo.subscribe("/dnd/cancel",this,'_onDndCancel');
			}


			this.connect(window, "onkeypress", "_onKeypress");
		},

		_hideTransparentColorBoxes: function(/*Array*/colorBoxes) {
			for( var i=0,l=colorBoxes.length ; i<l ; i++ ) {
				if(!this._allowTransparency && colorBoxes[i].className.match('ColorBoxTransparent'))  {
					colorBoxes[i].style.display='none';
				} else {
					colorBoxes[i].style.display='';
				}
			}
		},

		_applyColor: function() {
		// summary: Pass selected color to target input.
		// tags: callback
			this._saveUserColors();

			if(this._assignedInput !== undefined) {
				this._assignedInput.value=this.hexInputLayerNode.value;
			}
			epages.event.fire(this._assignedInput,"change");
			this._assignedInput=undefined;
			this.hide();
		},

		_findPosition: function(el){
			var positionX = 0;
			var positionY = 0;
			if (el.offsetParent) {
				while(el.offsetParent) {
						positionX += el.offsetLeft;
						positionY += el.offsetTop;
						el = el.offsetParent;
					}
			}
			return{
				positionX:positionX,
				positionY:positionY
			};
		},

		_mouseMoveOverGradient: function(evt) {
			evt = evt || window.event;
			var gradientX = evt.clientX-1-this._positionGradient.positionX;
			var gradientY = evt.clientY-1-this._positionGradient.positionY;
			if(gradientX > 255){
				gradientX = 255;
			}
			if(gradientX < 0){
				gradientX = 0;
			}
			if(gradientY > 255){
				gradientY = 255;
			}
			if(gradientY < 0){
				gradientY = 0;
			}
			sat = Math.round(gradientX*100/255);
			lum = Math.round(100-(gradientY*100/255));

			this.setCurrentColor({ h:this.currentColor.h, s:sat, b:lum});
		},
		_mouseMoveOverSlider: function(evt) {
			evt = evt || window.event;
			var sliderY      = evt.clientY-1-this._positionSlider.positionY-5;
			if(sliderY > 255){
				sliderY = 255;
			}
			if(sliderY < 0){
				sliderY = 0;
			}
			var hue = 360-((sliderY*360)/255);
			this.setCurrentColor({ h:hue, s:this.currentColor.s, b:this.currentColor.b});
		},

		_gradientMouseMove: function(evt){
			if(this._isGradientPushed){
				this._mouseMoveOverGradient(evt);
			}
		},

		_sliderMouseMove: function(evt) {
			if (this._isSliderPushed){
				this._mouseMoveOverSlider(evt);
			}
		},

		_gradientMouseDown: function(evt) {
			evt = evt || window.event;
			originalTarget = evt.originalTarget || evt.srcElement;
			this._positionGradient = this._findPosition(originalTarget);
			this._isGradientPushed=true;
			this._mouseMoveOverGradient(evt);
		},

		_gradientMouseUp: function(evt) {
			this._isGradientPushed = false;
		},

		_sliderMouseDown: function(evt) {
			evt = evt || window.event;
			originalTarget = evt.originalTarget || evt.srcElement;
			this._positionSlider = this._findPosition(originalTarget);
			this._isSliderPushed = true;
			this._mouseMoveOverSlider(evt);
		},

		_sliderMouseUp: function(evt) {
			this._isSliderPushed = false;
			this._setAllWizardColors();
		},

		_setRgbColor: function() {
			var rgb = {};

			try { rgb.r = Math.max(0, Math.min(255, parseInt(this.redInputLayerNode.value.match(/^\-?[0-9]+/g)[0]))); } catch (e) { rgb.r = 0; }
			try { rgb.g = Math.max(0, Math.min(255, parseInt(this.greenInputLayerNode.value.match(/^\-?[0-9]+/g)[0]))); } catch (e) { rgb.g = 0; }
			try { rgb.b = Math.max(0, Math.min(255, parseInt(this.blueInputLayerNode.value.match(/^\-?[0-9]+/g)[0]))); } catch (e) { rgb.b = 0; }

			this.setCurrentColor(rgb);
		},

		_setHexColor: function() {
		// summary: onchange callback function of hexInputLayerNode
		// tags: callback
			var colorValue = this.hexInputLayerNode.value;
			if(colorValue == "" && this.allowEmpty) {
				return false;
			}
			var hex = epages.validate.css.color2Hex(colorValue);
			if(hex){
				dojo.removeClass(this.hexInputLayerNode,'DialogError');
				this.setCurrentColor(epages.lang.color.hex2Rgb(hex));
			}
			else{
				dojo.addClass(this.hexInputLayerNode,'DialogError');
			}
			return true;
		},

		//Input HSB
		_setHsbColor: function() {
			var hsb = {};

			try { hsb.h = Math.max(0, Math.min(360, parseInt(this.hueInputLayerNode.value.match(/^\-?[0-9]+/g)[0]))); } catch (e) { hsb.h = 0; }
			try { hsb.s = Math.max(0, Math.min(100, parseInt(this.satInputLayerNode.value.match(/^\-?[0-9]+/g)[0]))); } catch (e) { hsb.s = 0; }
			try { hsb.b = Math.max(0, Math.min(100, parseInt(this.lumInputLayerNode.value.match(/^\-?[0-9]+/g)[0]))); } catch (e) { hsb.b = 0; }

			this.setCurrentColor(hsb);
		},

		setCurrentColor : function(rgbOrHsb) {
			// do not call recursive
			if (this._isInSetCurrentColor){
				return;
			}
			this._isInSetCurrentColor = true;

			var rgb = rgbOrHsb;
			var hsb = rgbOrHsb;
			if (rgbOrHsb.r === undefined){
				rgb = epages.lang.color.hsb2Rgb(rgbOrHsb);
			}
			if (rgbOrHsb.h === undefined){
				hsb = epages.lang.color.rgb2Hsb(rgbOrHsb);
			}
			this.setCurrentColorRgb(rgb);
			this.setCurrentColorHsb(hsb);

			this._isInSetCurrentColor = false;

			this._setWizardColors();
		},

		setCurrentColorRgb: function(rgb) {
			if(rgb.transparent) {
				this.curSelectedColor.className+=" CurSelectedTransparent";
			} else {
				this.curSelectedColor.className=this.curSelectedColor.className.replace(/ CurSelectedTransparent/g,"");
			}
			this.curSelectedColor.style.backgroundColor = epages.lang.color.rgb2Hex(rgb);

			dojo.removeClass(this.hexInputLayerNode,'DialogError');

			this.hexInputLayerNode.value = epages.lang.color.rgb2Hex(rgb);

			this.redInputLayerNode.value = Math.round(rgb.r);
			this.greenInputLayerNode.value = Math.round(rgb.g);
			this.blueInputLayerNode.value = Math.round(rgb.b);
		},

		setCurrentColorHsb : function(hsb){
			this.currentColor = hsb;
			this.hueInputLayerNode.value = Math.round(hsb.h) + "\xb0";
			this.satInputLayerNode.value = Math.round(hsb.s) + "%";
			this.lumInputLayerNode.value = Math.round(hsb.b) + "%";

			// slider
			var sliderY = Math.round(256*(360 - Math.round(hsb.h))/360);
			sliderY = sliderY<0?0:sliderY>255?255:sliderY;
			if (!this._isGradientPushed){
				this.colorSliderArrowNode.style.top = (sliderY)-Math.round(this.COLORSLIDER_IMAGE_HEIGHT/2)+'px';
			}
			// picker
			this.colorPickerSelectNode.style.top =  (256-(hsb.b*2.56)-Math.round(this.COLORPICKER_IMAGE_HEIGHT/2)) + 'px';
			this.colorPickerSelectNode.style.left = ((hsb.s*2.56)-Math.round(this.COLORPICKER_IMAGE_HEIGHT/2)) + 'px';
			this.colorLayerNode.style.backgroundColor = epages.lang.color.rgb2Hex(this.getBaseColor(sliderY,256));
			var rgb = epages.lang.color.rgb2Hex(this.getBaseColor(sliderY,256));
		},

		_onClickUserColor: function(evt) {
			var userColorNumber = (evt.currentTarget.id.split('_'))[1];
			//if current color is activated safe current color to user color
			if(this._activeCurrentColor){
				if (userColorNumber != this.numberOfUserColors-1){
					var definedColor = epages.lang.color.rgb2Hex(epages.lang.color.hsb2Rgb(this.currentColor));
					this._setUserColor(userColorNumber,definedColor);
					this._deactivateUserColors();
				}
			}
			//else set current color to user color
			else{
				this.setCurrentColor(this.userColors[userColorNumber].color);
			}
		},

		_setUserColor: function(colorNumber,/*color in hex*/color){
			if (colorNumber != this.numberOfUserColors-1){
				var id = 'UserDefinedColor'+(parseInt(colorNumber));
				if(!this._unsavedChanges){
					this._unsavedChanges = [];
				}
				this._unsavedChanges[id] = color;
				this.userColors[colorNumber].node.style.backgroundColor = color;
				this.userColors[colorNumber].color = epages.lang.color.hex2Rgb(color);
			}
		},

		_setWizardColor: function(evt) {
			var wizardColorNumber = (evt.currentTarget.id.split('_'))[1];
			this.setCurrentColor(this.wizardColors[wizardColorNumber].color);
			this.wizardColors[wizardColorNumber].node.className = "ColorBox";
		},

		_onClickCurrentColor: function(evt){
			this._activateUserColors(true);
			dojo.stopEvent(evt);
		},

		_activateUserColors: function(highlightCurrent){
				if(highlightCurrent) {
					dojo.addClass(this.curSelectedColor,"CurSelectedColorActive");
					this._activeCurrentColor = true;
				}
				dojo.addClass(this.userColorsNode,"Active");
		},

		_deactivateUserColors: function() {
			dojo.removeClass(this.curSelectedColor,"CurSelectedColorActive");
			this._activeCurrentColor = false;
			dojo.removeClass(this.userColorsNode,"Active");
		},

		_saveUserColors: function() {
			if(this._unsavedChanges){
				var data = {
					'GUID' : [],
					'Name'     : [],
					'Value'    : []
				};
				for(el in this._unsavedChanges){
					data.GUID.push(this.objectId);
					data.Name.push(el);
					data.Value.push(this._unsavedChanges[el]);
				}
				if (this.objectId == '') {
					console.warn('ColorPicker has no ObjectId, can\'t save data on server ('+data+').');
				} else {
					dojo.require('epages.cartridges.de_epages.presentation.objectupdater');
					var styleUpdater = new epages.cartridges.de_epages.presentation.ObjectUpdater();
					styleUpdater.sendAsync('?',data);
					this._unsavedChanges = undefined;
				}
			}
		},

		_setWizardColors: function() {
			switch(this.currentWizardScheme){
				case "Compound":
					this.compoundColorWizard(this.curSelectedColor.style.backgroundColor, this.wizardColors);
					this.compoundTitle.style.fontWeight = 'bold';
					this.complementaryTitle.style.fontWeight = 'normal';
					this.analogueTitle.style.fontWeight = 'normal';
					this.triadTitle.style.fontWeight = 'normal';
					this.compoundRadio.setChecked(true);
					break;
				case "Complementary":
					this.complementaryColorWizard(this.curSelectedColor.style.backgroundColor, this.wizardColors);
					this.complementaryTitle.style.fontWeight = 'bold';
					this.compoundTitle.style.fontWeight = 'normal';
					this.analogueTitle.style.fontWeight = 'normal';
					this.triadTitle.style.fontWeight = 'normal';
					this.complementaryRadio.setChecked(true);
					break;
				case "Analogue":
					this.analogueColorWizard(this.curSelectedColor.style.backgroundColor, this.wizardColors);
					this.analogueTitle.style.fontWeight = 'bold';
					this.compoundTitle.style.fontWeight = 'normal';
					this.complementaryTitle.style.fontWeight = 'normal';
					this.triadTitle.style.fontWeight = 'normal';
					this.analogueRadio.setChecked(true);
					break;
				case "Triad":
					this.triadColorWizard(this.curSelectedColor.style.backgroundColor, this.wizardColors);
					this.triadTitle.style.fontWeight = 'bold';
					this.compoundTitle.style.fontWeight = 'normal';
					this.complementaryTitle.style.fontWeight = 'normal';
					this.analogueTitle.style.fontWeight = 'normal';
					this.triadRadio.setChecked(true);
					break;
				default:
					break;
			}
		},

		_setAllWizardColors: function() {
			setTimeout(dojo.hitch(this, function() {
				this.compoundColorWizard(this.curSelectedColor.style.backgroundColor, this.compoundColors);
				this.complementaryColorWizard(this.curSelectedColor.style.backgroundColor, this.complementaryColors);
				this.analogueColorWizard(this.curSelectedColor.style.backgroundColor, this.analogueColors);
				this.triadColorWizard(this.curSelectedColor.style.backgroundColor, this.triadColors);
			}), 1);
		},

		_switchWizard: function() {
			this.ColorChooser.style.display = 'none';
			this.ColorWizard.style.display = 'block';
			this.switchWizard.className = 'ColorPickerTabActive';
			this.switchPicker.className = 'ColorPickerTab';
			this._setWizardColors();
		},

		_switchPicker: function() {
			this.ColorWizard.style.display = 'none';
			this.ColorChooser.style.display = '';
			this.switchWizard.className = 'ColorPickerTab';
			this.switchPicker.className = 'ColorPickerTabActive';
		},

		_setWizardScheme: function(wizardScheme) {
			this.currentWizardScheme = wizardScheme;
			this._setWizardColors();
			if(!this._unsavedChanges){
				this._unsavedChanges = [];
			}
			this._unsavedChanges['WizardScheme'] = this.currentWizardScheme;
		},

		getBaseColor: function(sliderPos, sliderLength){
			var n=sliderLength/6, j=sliderLength/n, C=sliderPos, c=C%n;
			return {r:C<n?255:C<n*2?255-c*j:C<n*4?0:C<n*5?c*j:255, g:C<n*2?0:C<n*3?c*j:C<n*5?255:255-c*j, b:C<n?c*j:C<n*3?255:C<n*4?255-c*j:0};
		},

		_setActiveWizardColor: function(evt){
			var wizardColorNumber = (evt.currentTarget.id.split('_'))[1];
			this._activeWizardColor = this.wizardColors[wizardColorNumber].node.style.backgroundColor;
		},

		_onDndStart: function(source,nodes,iscopy){
			var color = "";
			if(nodes[0].style.backgroundColor != ""){
				color = nodes[0].style.backgroundColor;
				this._activateUserColors(true);
			} else{
				color = this._activeWizardColor;
				this._activateUserColors(false);
			}
			this._hideAvatar();
			this._blockAvatar = true;
			dojo.addClass(document.body,'DNDColor');
			dojo.addClass(document.body,'dropNotAllowed');
			dojo.dnd.manager().avatar.node.style.backgroundColor = color;
			dojo.dnd.manager().avatar.node.style.zIndex = epages.zIndex + 3000;
		},

		_onDndDrop: function(source,nodes,iscopy){
			dojo.removeClass(document.body,'DNDColor');
			dojo.removeClass(document.body,'dropNotAllowed');
			var wizardColorNumber = source.node.id.split('_')[1];
			var targetElement = dojo.dnd.manager().target;
			targetElement.node.innerHTML = "";
			var colorNumber = targetElement.node.id.split('_')[1];
			var definedColor;
			if(wizardColorNumber){
				definedColor = epages.lang.color.rgb2Hex(this.wizardColors[wizardColorNumber].color);
			}
			else{
				definedColor = epages.lang.color.rgb2Hex(epages.lang.color.hsb2Rgb(this.currentColor));
			}
			if(colorNumber){
				this._setUserColor(colorNumber,definedColor);
			}
			this._deactivateUserColors();
			this._blockAvatar = false;
		},

		_onDndCancel: function(source,nodes,iscopy){
			dojo.removeClass(document.body,'DNDColor');
			dojo.removeClass(document.body,'dropNotAllowed');
			this._blockAvatar = false;
			this._deactivateUserColors();
		},

		_showAvatar: function(evt){
			var color = evt.currentTarget.style.backgroundColor;
			if(!this._blockAvatar){
				if(!this._avatar){
					var avatar = document.createElement('div');
					avatar.id ="colorPickerMouseAvatar";
					avatar.style.position = "absolute";
					avatar.style.zIndex = "25000";
					avatar.style.border ="1px solid black";
					avatar.style.width = "12px";
					avatar.style.height = "12px";
					document.body.appendChild(avatar);
					this._avatar = $('colorPickerMouseAvatar');
					this._avatar.style.backgroundColor = color;
				}
				else{
					this._avatar.style.display = "";
					this._avatar.style.backgroundColor = color;
				}
			}
		},

		_moveAvatar: function(evt){
			var x = (document.all ? window.event.x : evt.pageX) + 6;
			var y = (document.all ? window.event.y : evt.pageY) + 15;
			if(this._avatar){
				this._avatar.style.left = x + "px";
				this._avatar.style.top = y + "px";
			}
		},

		_hideAvatar: function(evt){
			if(this._avatar){
				this._avatar.style.display = "none";
			}
		},

		_closeColorPicker:function(){
			//save user defined colors
			this._saveUserColors();
			this.hide();
		},

		_onKeypress: function(/* Event */ evt) {
		// summary: keypress event controller
		// tags: callback
			if(evt.keyCode == dojo.keys.ESCAPE) {
				this.hide();
			}
		}
});