/**
 * Wooden Sign updating and styling script
 * @author AppSol
 * @version 0.1
 * @copyright Appropriate Solutions 2008
 */
if (typeof YD == 'undefined') var YD = YAHOO.util.Dom;
if (typeof YE == 'undefined')var YE = YAHOO.util.Event;
if (typeof $ == 'undefined')var $ = YD.get;

YAHOO.cmsLite.sign = {
	signBox : null,
	signBoxPara : null,
	signBoxSpan : null,
	signBoxButtons : [],
	textBox : null,
	fontInputs : null,
	fontImages : [],
	styleInputs : null,
	styleImages : [],
	shadowDiv : null,
	fontChoice : null,
	styleChoice : null,
	/**************
	 * 
	 */
	init : function(){
		/*******
		 * Create the signBox div, this will be the parent div for the 2 signBoxParas
		 */
		this.signBox = $('content').appendChild(document.createElement('div'));
		this.signBox.setAttribute('id', 'signbox');
		var signType = String(document.forms['product_form']['type'].value);
		YD.addClass(this.signBox, signType);
		var signBoxWarning = $('content').appendChild(document.createElement('p'));
		signBoxWarning.innerHTML = 'for illustrative purposes only';
		signBoxWarning.setAttribute('id', 'signbox_warn');
		/******
		 * The signBoxParas are created as array element node refs
		 * We just create the first singBoxPara here and give it a starting font size
		 */
		this.signBoxPara = new Array();
		this.signBoxPara[0] = this.signBox.appendChild(document.createElement('p'));
		this.signBoxPara[0].style.fontSize = '8em';
		
		/******
		 * Collect the node refs for the sign text inputs into a class property
		 * then disable the second line text input.
		 * This stays disabled until text is entered into the first line input
		 * so the signBox rendering is not messed up.
		 */
		this.textBox = $('text').getElementsByTagName('input');
		this.textBox[1].style.display = 'none';
		/******
		 * Collect the node refs for the font selection radios.
		 * Create the img icons which will launch the font example popups
		 */
		this.fontInputs = document.forms['product_form']['font'];
		for (var i=0; i<this.fontInputs.length; i++) {
			if(this.fontInputs[i].checked) this.fontChoice = this.fontInputs[i].value;
			this.fontImages[i] = document.createElement('img');
			var fontLabel = YD.getNextSibling(this.fontInputs[i]);
			fontLabel.innerHTML = '';
			this.fontImages[i] = fontLabel.appendChild(this.fontImages[i]);
			this.fontImages[i].setAttribute('title', 'click to see an example of '+this.fontInputs[i].title);
			this.fontImages[i].setAttribute('alt', 'example of '+this.fontInputs[i].title);
			this.fontImages[i].setAttribute('src', '/images/abc_'+this.fontInputs[i].id+'_tmb.jpg');
			YE.on(this.fontImages[i], 'mouseover', function(){
				YD.addClass(this, 'hover');
			});
			YE.on(this.fontImages[i], 'mouseout', function(){
				YD.removeClass(this, 'hover');
			});
			YE.on(this.fontImages[i], 'click', this.panelPop, this, true)
		};
		/*******
		 * Collect the node refs for the style selection radios
		 * Create the img icons which will launch the style example popups
		 */
		this.styleInputs = document.forms['product_form']['style'];
		for (var i=0; i<this.styleInputs.length; i++) {
			if(this.styleInputs[i].checked) this.styleChoice = this.styleInputs[i].value;
			this.styleImages[i] = document.createElement('img');
			var styleLabel = YD.getNextSibling(this.styleInputs[i]);
			styleLabel.innerHTML = '';
			this.styleImages[i] = styleLabel.appendChild(this.styleImages[i]);
			this.styleImages[i].setAttribute('title', 'click to see an example of '+this.styleInputs[i].title);
			this.styleImages[i].setAttribute('alt', 'example of '+this.styleInputs[i].title);
			this.styleImages[i].setAttribute('src', '/images/'+this.styleInputs[i].id+'_style_tmb.jpg');
			YE.on(this.styleImages[i], 'mouseover', function(){
				YD.addClass(this, 'hover');
			});
			YE.on(this.styleImages[i], 'mouseout', function(){
				YD.removeClass(this, 'hover');
			});
			YE.on(this.styleImages[i], 'click', this.panelPop, this, true)
		};
		YD.addClass(this.signBox, this.styleChoice);
		/*****
		 * Set the events we are going to react to.
		 */
		YE.on(this.textBox, 'keyup', this.updateSignText, this, true);
		YE.on(this.fontInputs, 'click', this.updateSignFont, this, true);
		YE.on(this.styleInputs, 'click', this.updateSignStyle, this, true);
		YE.on(document.forms['product_form']['reset'], 'click', this.resetForm, this, true);
		YE.on(document.forms['product_form'], 'submit', this.submitForm, this, true);
		/********
		 * Create the signBoxSpan array of node refs to the spans within signBox
		 * that actually hold the sign text.
		 * Spans are required as they are inline elements and so have variable width.
		 * We only create the first span as a child of the first signBoxPara
		 */
		this.signBoxSpan = new Array();
		this.signBoxSpan[0] = this.signBoxPara[0].appendChild(document.createElement('span'));
		this.signBoxSpan[0].style.fontSize = '1em';
		/*****
		 * Set the initial font style depending on the font choice
		 */
		this.setSignStyle(this.signBoxSpan[0], this.fontChoice);
	},
	/************
	 * Set Sign Style
	 * Updates the font of the span depending upon which radio button was clicked
	 * @param {Object} signSpan
	 * @param {Object} font
	 */
	setSignStyle : function(signSpan, font){
		signSpan.style.lineHeight = '1em';
		signSpan.style.fontWeight = '600';
		switch(font) {
			case 'sans':
				signSpan.style.fontFamily = 'Arial, Helvetica, sans-serif';
				signSpan.style.fontStyle = 'normal';
				break;
			case 'serif':
				signSpan.style.fontFamily = 'Georgia, Times, serif';
				signSpan.style.fontStyle = 'normal';
				break;
			case 'italic':
				signSpan.style.fontFamily = 'Georgia, Times, serif';
				signSpan.style.fontStyle = 'oblique';
				break;
		}
	},
	/*********
	 * Update Sign Text
	 * Updates the text value of each signBoxSpan.
	 * Called on each keyup event from the sign text inputs
	 * @param {Object} e
	 */
	updateSignText : function(e){
		var textBox = YE.getTarget(e);
		var signText = textBox.value;
		/****
		 * Strip unsafe characters
		 */
		signText = signText.replace(/[^a-zA-Z0-9\s,\.'"]/gi, '');
		/*****
		 * If this is sign_text_1 we need to check to see if sign_text_2 is disabled
		 * If so we can now enable it as text entry has begun in the first text box.
		 * We can then simply update the span contents
		 */
		if(textBox.id == 'sign_text_1'){
			var textBox2 = document.getElementById('sign_text_2');
			if (textBox2.style.display == 'none') textBox2.style.display = 'block';
			this.signBoxSpan[0].innerHTML = signText;
		}else{
			/*****
			 * If this is sign_text_2 we need to see if the p and span for the second line
			 * of sign text has been created.
			 */
			if (typeof this.signBoxSpan[1] == 'undefined' || !this.signBoxSpan[1]) {
				/****
				 * Create a p and span for the second sign text line.
				 * Set the font size, and font choice
				 */
				this.signBoxPara[1] = this.signBox.appendChild(document.createElement('p'));
				this.signBoxPara[1].style.fontSize = '6em';
				this.signBoxSpan[1] = this.signBoxPara[1].appendChild(document.createElement('span'));
				this.signBoxSpan[1].style.fontSize = '1em';
				this.setSignStyle(this.signBoxSpan[1], this.fontChoice);
				/*******
				 * Create the font size adjustment buttons
				 */
				for (var i=1; i<3; i++) {
					this.signBoxButtons[i] = document.createElement('a');
					this.signBoxButtons[i].setAttribute('id', 'font_button_'+i);
					this.signBoxButtons[i].setAttribute('class', 'font_button');
					this.signBoxButtons[i].setAttribute('href', '#');
					this.signBoxButtons[i].setAttribute('title', 'change the size of the sign text');
					this.signBoxButtons[i].appendChild(document.createTextNode('+'));
					$('content').appendChild(this.signBoxButtons[i]);
					YE.on(this.signBoxButtons[i], 'click', this.changeFontSize, this, true);
				};
			}else {
				/****
				 * Got the elements we need, so just update the text value.
				 * If the text value turns out to be '' (empty), then we can remove the p and span
				 */
				this.signBoxSpan[1].innerHTML = signText;
				if (signText == '') {
					this.signBoxPara[1].removeChild(this.signBoxSpan[1]);
					this.signBox.removeChild(this.signBoxPara[1]);
					this.signBoxSpan[1] = null;
					this.signBoxPara[1] = null;
				}
			}
		}
		/****
		 * Recalculate all the font sizes
		 */
		this.updateFontSize();
	},
	/*********
	 * Update Sign Font
	 * called in response to a change in font choice
	 * calls the function to change the font in the signBox
	 * then calls the function to recalculate the font size
	 * @param {Object} e
	 */
	updateSignFont : function(e){
		var fontRadio = YE.getTarget(e);
		this.fontChoice = fontRadio.value;
		for (var i=0; i<this.signBoxSpan.length; i++) {
			this.setSignStyle(this.signBoxSpan[i], this.fontChoice);
			this.updateFontSize(this.signBox, this.signBoxSpan[i]);
		}
		fontRadio.checked = true;
	},
	/************
	 * Update Sihn Style
	 * called in response to a change in sign style choice
	 * changes the class of the sign box to reflect the choice
	 * used to update the background image
	 * @param {Object} e
	 */
	updateSignStyle : function(e){
		var styleRadio = YE.getTarget(e);
		YD.hasClass(this.signBox, 'relief')? YD.replaceClass(this.signBox, 'relief', 'engraved') : YD.replaceClass(this.signBox, 'engraved', 'relief');
		styleRadio.checked = true;
	},
	/********
	 * Change Font Size
	 * asynchronously changes the size of one of the text lines
	 * and adjust the size of the other to fit
	 */
	changeFontSize : function(e){
		var fontButton = YE.getTarget(e);
		var pUp = fontButton.id == 'font_button_1'? 0 : 1;

		for(var i=0; i<this.signBoxPara.length; i++){
			var fS = parseFloat(this.signBoxPara[i].style.fontSize);
			if(isNaN(fS)) return;
			fS = i == pUp? fS+0.1 : fS-0.1;
			this.signBoxPara[i].style.fontSize = fS+'em';
		}
		this.updateFontSize();
	},
	/*********
	 * Update Font Size
	 * Recalculates the font sizes for the signBox text
	 * depending upon number of lines, and font choice
	 */
	updateFontSize : function(){
		/*****
		 * First gather some dimensions for the signBox itself
		 */
		var signBox = document.getElementById('signbox');
		var boxDim = YD.getRegion(signBox);
		var boxWidth = boxDim['right']-boxDim['left'];
		var boxHeight = boxDim['bottom']-boxDim['top'];
		/****
		 * Calculate the number of pixels per em
		 */
		var emPx = Math.floor(boxWidth / 42);
		/****
		 * Get the p and spans into arrays and set up a few variables
		 */
		var signBoxPara = signBox.getElementsByTagName('p');
		var signBoxSpan = signBox.getElementsByTagName('span');
		var signDim = new Array();
		var signWidth = 0;
		var signHeight = 0;
		var signText = new Array();
		/****
		 * Gather some information about each span and put them into the arrays
		 * so we have width, height and text value of each sign
		 */
		for (var i=0; i<signBoxSpan.length; i++) {
			signDim[i] = YD.getRegion(signBoxSpan[i]);
			signDim[i]['height'] = signDim[i]['bottom']-signDim[i]['top'];
			signDim[i]['width'] = signDim[i]['right']-signDim[i]['left'];
			signText[i] = signBoxSpan[i].innerHTML;
			/****
			 * We can now start to add up the total sign size.
			 * First the sign height is the sum of the span heights
			 */
			signHeight+= signDim[i]['height']+emPx;
			/****
			 * If this is the widest span so far,
			 * then set the total sign width to be the same as the span width
			 * and set the largest character count to be the length of the span text string
			 */
			if(signDim[i]['width']>signWidth){
				signWidth = signDim[i]['width'];
				var signTextMax = signText[i].length;
			}
		}
		/******
		 * If the sign height is greater than the containing div
		 * or the sign width is greater than the containing div
		 * shrink the font size by 0.1 then recalculate the dimensions
		 */
		while(signHeight>(boxHeight-2*emPx) || signWidth>(boxWidth-8*emPx)){
			for(var i=0; i<signBoxPara.length; i++){
				var fS = parseFloat(signBoxPara[i].style.fontSize);
				if(isNaN(fS)) return;
				fS = fS-0.2;
				signBoxPara[i].style.fontSize = fS+'em';
			}
			signWidth = 0;
			signHeight = 0;
			for (var i=0; i<signBoxSpan.length; i++) {
				signDim[i] = YD.getRegion(signBoxSpan[i]);
				signDim[i]['height'] = signDim[i]['bottom']-signDim[i]['top'];
				signDim[i]['width'] = signDim[i]['right']-signDim[i]['left'];
				signHeight+= signDim[i]['height'];
				signWidth = signDim[i]['width']>signWidth? signDim[i]['width'] : signWidth;
			}
		}
		/******
		 * If the sign height is less than the containing div 
		 * AND the sign width is less than the containing div
		 * then increase the font size by 0.1 and recalculate the dimensions
		 */
		while(signHeight<(boxHeight-2*emPx) && (signWidth+(signWidth/signTextMax))<(boxWidth-8*emPx)){
			for(var i=0; i<signBoxPara.length; i++){
				var fS = parseFloat(signBoxPara[i].style.fontSize);
				if(isNaN(fS)) return;
				fS = fS+0.2;
				signBoxPara[i].style.fontSize = fS+'em';
			}
			signWidth = 0;
			signHeight = 0;
			for (var i=0; i<signBoxSpan.length; i++) {
				signDim[i] = YD.getRegion(signBoxSpan[i]);
				signDim[i]['height'] = signDim[i]['bottom']-signDim[i]['top'];
				signDim[i]['width'] = signDim[i]['right']-signDim[i]['left'];
				signHeight+= signDim[i]['height'];
				signWidth = signDim[i]['width']>signWidth? signDim[i]['width'] : signWidth;
			}
		}
		return;
	},
	/*******
	 * Reset Form
	 * resets the form to it's initial values
	 * @param {Object} e
	 */
	resetForm : function(e){
		YE.preventDefault(e);
		this.textBox[0].value = '';
		this.textBox[1].value = '';
		for (var i=0; i<this.fontInputs.length; i++) {
			if(this.fontInputs[i].value == this.fontChoice) this.fontInputs[i].checked = true;
		};
		for (var i=0; i<this.styleInputs.length; i++) {
			if(this.styleInputs[i].value == this.styleChoice) this.styleInputs[i].checked = true;
		};
		if (typeof this.signBoxPara[1] != 'undefined'){
			this.signBox.removeChild(this.signBoxPara[1]);
			this.signBoxPara[1] = null;
		}
		
		while(this.signBoxPara[0].lastChild){
			this.signBoxPara[0].removeChild(this.signBoxPara[0].lastChild);
		}
		this.signBoxPara[0].style.fontSize = '9em';
		this.signBoxSpan = new Array();
		this.signBoxSpan[0] = this.signBoxPara[0].appendChild(document.createElement('span'));
		this.signBoxSpan[0].style.fontSize = '1em';
		this.setSignStyle(this.signBoxSpan[0], this.fontChoice);
		return;
	},
	/**********
	 * Submit Form
	 * fills the hidden form fields with the values gained from
	 * the sign box. Each line of text is measured as a percentage
	 * of the sign height
	 * @param {Object} e
	 */
	submitForm : function(e){
		var boxDim = YD.getRegion(this.signBox);
		var boxHeight = boxDim['bottom']-boxDim['top'];
		var sizes = new Array();
		for (var i=0; i<this.signBoxSpan.length; i++) {
			var spanDim = YD.getRegion(this.signBoxSpan[i]);
			var spanHeight = spanDim['bottom']-spanDim['top'];
			sizes[i] = Math.floor((spanHeight/boxHeight)*100);
		};
		document.forms['product_form']['first_line_text'].value = this.signBoxSpan[0].innerHTML;
		document.forms['product_form']['first_line_size'].value = sizes[0];
		if(this.signBoxSpan.length==2){
			document.forms['product_form']['second_line_text'].value = this.signBoxSpan[1].innerHTML;
			document.forms['product_form']['second_line_size'].value = sizes[1];
		}
		return;
	},
	/*********
	 * Panel Pop
	 * creates the pop-up object
	 * @param {Object} e
	 */
	panelPop : function(e){
		var thumbImg = YE.getTarget(e);
		var imgSrc = String(thumbImg.src);
		var imgArr = imgSrc.split('_tmb');
		imgSrc = imgArr[0]+imgArr[1];
		var panel = new YAHOO.widget.Panel("att_demo",{
			width : "410px",
			underlay : "matte",
			fixedcenter : true,
			close : true,
			visible : true,
			draggable : false,
			modal : true,
			effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.25}});
		panel.setHeader(thumbImg.alt);
		var panelBody = '<img src="'+imgSrc+'" alt="'+thumbImg.alt+'" />';
		panelBody+= '<p>Image illustrates actual letter styling used</p>';
		panel.setBody(panelBody);
		panel.render(document.body);
	}
};

var YCS = YAHOO.cmsLite.sign;

YE.onDOMReady(YCS.init, YCS, true);
