/*
Suttle AJAX Configurator
Jason Barney - First Scribe Inc. - Last Rev 8/25/09
12/26/07 - update to Scriptalicious 1.8.0 from 1.7.0
1/21/08 - improved draggability, corrected outlets
7/23/09 - Ben Koren <bkoren@firstscribe.com> - added grid snapping, trash bin, image rotation
8/25/09 - Jason Barney <jbarney@firstscribe.com> - rewrote cover selector for multiple styles and eliminated helper functions for BOM
*/
var ComponentCount = 0;
var ComponentTracker = Array();  //invisible array for tracking element positioning
//var RemoveMe;
var encRegion; //the enclosure region, doesn't change
//var trashRegion;
var selectedElement;
/* Menus */
var ActiveMenu;
//var ActiveMenu = 'voice';
var MenuSpeed = 1; //menuspeed in seconds
/* Enclosure & Cover Swaps - tracking explicityly is easier, capture on form submit */
var ActiveEnclosure = 'enclosure-sae14';
var ActiveEnclosureStyle = 'sae14';
var ActiveCover = 'SAE-14DC';
var PlugsAvailable = new Hash({sae14: 2,sae21: 4, sae28: 4, sae42:4});  //prototype hash
var PlugsUsed = 0;
//Refresh the mini view of the Bill of Materials
function CreateBill(){
	//holder
	var h = new Hash();
	var encstring = ActiveCover;
	$('bill').innerHTML =  "<br><div class=\"modmin\">Enclosure: </div><div class=\"part_qty\">" + encstring + "</div><br>";
	for(var i = 0; i < ComponentTracker.length; i++){ 
		var thisModule = ComponentTracker[i].id.split("_");
		//check if this hash value is set
		var thiskey = thisModule[0].toString();  //retuns the module 'SAM-V10'
		if(h.get(thiskey)){
			h.set(thiskey,h.get(thiskey) + 1); 
		} else {
			h.set(thiskey,1); 
		}
	}
	//fill out html
	h.each(function(thisval) {
		$('bill').innerHTML += "<div class=\"modmin\">" + thisval.key + "</div><div class=\"part_qty\">[" + thisval.value + "]</div><br>";
	});
	MarkPlugs();  //update the plugs
}

//the error output section
function ErrorMessage(type){
	switch(type){
		case "plugs":$('errors').innerHTML = "<h3>Warning</h3><p>This enclosure does not meet power requirements.</p><p> Please choose a larger enclosure, reduce the number of powered modules, purchase our <a href=\"http://www.suttleonline.com/catalog/structured-wiring/soho-enclosures/enclosure-power/3-outlet-ac-power-extention.html\" target=\"_blank\">SAE-PS3</a> Power Extender, or make other arrangement to facilitate your increased power needs.</p>";
			$('errorflag').style.display = 'block';
			break;
		case "overlap": $('errors').innerHTML = "<h3>Warning</h3><p>Some components are overlapping.</p><p>Please move modules, delete modules, or choose a larger enclosure to correct your component layout overlap. </p>";
			$('errorflag').style.display = 'block';
			break;
		default:	$('errors').innerHTML = "";
		$('errorflag').style.display = 'none';
			break;
	}
}

//intermediate tracking function for del/garbage compatability
function Track(draggable){ //hooks through draggable.onEnd
	var thisregion =  YAHOO.util.Dom.getRegion(draggable.element);
		
	if(thisregion.intersect(YAHOO.util.Dom.getRegion($('trash')))) {
		//delHandle();
	}
	else {
		TrackElement(draggable.element); 
		MarkOverlaps();
	}
}

function TrackElement(element) { //tweak this for better overlap functionality
	//set the enclosure region if it has not been set
	/*
	if(encRegion == null)
		encRegion = YAHOO.util.Dom.getRegion('enclosure'); 
	
	thisregion =  YAHOO.util.Dom.getRegion(element);
	//check if its in the draggable area
	var e_intersect = thisregion.intersect(encRegion);
	if(e_intersect)
	*/
		ComponentTracker.push(element);
	//check if its in the garbage
	//var g_intersect = thisregion.intersect(trashRegion);
	//if(g_intersect) element.hide();
}
function UnTrack(element){
	TempComponenetTracker = Array(); //copy array
	for(var i = 0; i <  ComponentTracker.length; i++){
		if(element == ComponentTracker[i]) {
			//remove the element
			ComponentTracker[i] = '';
		} else TempComponenetTracker.push(ComponentTracker[i]);
	}
	ComponentTracker = TempComponenetTracker; //set original array = to temp copy
	MarkOverlaps();
}
//get all elements with class 'selected' and remove the class'
function ClearFlag(className){
	for(var i = 0; i < ComponentTracker.length; i++)
	{
		 ComponentTracker[i].removeClassName(className);
		 restoreOpacity(ComponentTracker[i]);
	}
}	

//flip horizontal and vertical images
function SwapImage() {
	var tmp = selectedElement.rel;
	alert(tmp);
}


function restoreOpacity(element) {
	//don't set these, delete these
	try {
		element.style.opacity = '1.0';
		element.style.filter =  "Alpha(Opacity=100)";
	} catch(e) {}
}

function selectElement(draggable) {
	if(selectedElement)restoreOpacity(selectedElement);
	
	try {
		selectedElement = draggable;
		selectedElement.style.opacity = '0.7';
		selectedElement.style.filter =  "Alpha(Opacity=70)";
	} catch(e) {}
}

//this callback function is called when you start dragging a draggable
function StartDrag(draggable, mousesevent){
	selectElement(draggable.element);
	UnTrack(draggable.element);
}

function delHandle(){ //this is called prior to the onEnd draggable handler
	if (Object.isElement(selectedElement)) {
		UnTrack(selectedElement); //can't remove anything but selected
		//selectedElement.stopObserving('click', flagSelected);
		selectedElement.parentNode.removeChild(selectedElement);
		selectedElement = '';
		MarkOverlaps();
	}
}

//go through the components and flag all those that overlap
function MarkOverlaps(){
	var intersection = false;
	for(var i = 0; i < ComponentTracker.length; i++){
		var thisregion =  YAHOO.util.Dom.getRegion(ComponentTracker[i]);
		
		for(var j = i+1; j < ComponentTracker.length; j++){ //check all elements after this one
			if(thisregion.intersect(YAHOO.util.Dom.getRegion(ComponentTracker[j]))) {
				//flag both elements
				ComponentTracker[i].addClassName('nodrop');
				ComponentTracker[j].addClassName('nodrop');
				//new Effect.Move(ComponentTracker[j],{x:0,y:50, mode:'relative'});
				intersection = true;
			}
		}
	}
	/*if(intersection == true){
		ErrorMessage('overlap');
	} 
	else {*/
		ErrorMessage('clear');
		ClearFlag('nodrop');
	//}
	CreateBill();  //update the mini bill of materials
}

//added 1/21/08 mouse position for use in CreateDragElement
function getPosition(e){
	var left = 0;
	var top  = 0;

	while (e.offsetParent){
		left += e.offsetLeft;
		top  += e.offsetTop;
		e     = e.offsetParent;
	}

	left += e.offsetLeft;
	top  += e.offsetTop;

	return {x:left, y:top};
}

//create draggable element in the proper div
//1/25/08 need an onclick this style == selected
//2/06/08 dependencies
function CreateDragElement(element,flip,top_offset,left_offset){
	//alert(top);alert(left);
	ComponentCount++;
	
	// if we are creating the element due to a flip request
	if(flip && element.alt != '') {
		var tempid = substr(element.id,0,element.id.lastIndexOf('_')) + '_' + ComponentCount;
		var tempsrc = element.alt;
		var tempalt = element.src;
	}
	else {
		var tempid = element.id + '_' + ComponentCount;	
		var tempsrc = element.src;
		var tempalt = element.alt;
	}
	
	var tempwidth = element.offsetWidth;
	var tempheight = element.offsetHeight;
	//var tempalt = element.alt;
	
	//if powered add that class
	if($(element).hasClassName('powered')){
		var draggable = Builder.node('img',
			{
			src: tempsrc,
			alt: tempalt,
			id: tempid,
			className: "dragme powered"
			}
		);
	} else {
		var draggable = Builder.node('img',
			{
			src: tempsrc,
			alt: tempalt,
			id: tempid,
			className: "dragme"
			}
		);
	}
	//append newly created element to the stage
	$('enclosure').appendChild(draggable,{position: 'absolute'});
	try { // IE fix
		$(draggable).setStyle({
			top: top_offset,
			left: left_offset
		});
	} catch (e) {}
	//add draggability
	var ele = $(tempid);
	//add listener for responsive clicking
	$(ele).observe('click', flagSelected);
	
	
	/*var browserName=navigator.appName; 
	var browserVer=parseInt(navigator.appVersion); 
	if (browserName=="Microsoft Internet Explorer" && browserVer <= 7) {
		var thisdraggable = new Draggable(ele,{
			onStart: StartDrag,
			onEnd: Track
		});
	}
	else {*/
		var thisdraggable = new Draggable(ele,{
			onStart: StartDrag,
			onEnd: Track,
			snap: function(x,y) {
				var x_min = 25;
				var y_min = 10;
				var x_snap = 9.4; // 235 / 25
				var y_snap = 9.3506493506493506493506493506494 // 720/77
				
				var x_new = (x < x_min) ? x_min : Math.round((x-x_min)/x_snap)*x_snap+x_min;
				var y_new = (y < y_min) ? y_min : Math.round((y-y_min)/y_snap)*y_snap+y_min;
				
				return [x_new, y_new];
			}
		});
	//}
	
	
	
	//dependent modules
	
	/*if(tempalt){ //check
		//powered?
		var thisClassName;
		if($(tempalt).hasClassName('powered')) 	thisClassName = "dragme powered";
		else thisClassName = "dragme";

		ComponentCount++;
		var tempid2 = $(tempalt).id + '_' + ComponentCount;
		var draggable2 = Builder.node('img',
			{
			src: $(tempalt).src,
			id: tempid2,
			className: thisClassName
			}
		);
		//append newly created element to the stage
		$('enclosure').appendChild(draggable2,{position: 'absolute'});
		//add draggability
		var ele2 = $(tempid2);
		//add listener for responsive clicking
		$(ele2).observe('click', flagSelected);
		var thisdraggable2 = new Draggable(ele2,{
			onStart: StartDrag,
			onEnd: Track//,
		});
	}*/ //end dep module
	
	TrackElement(ele);
	return ele;
}

//a click hander to better handle interactivity
function flagSelected(event) {
	if (event.detail == 2) {// double click
		flipSelected();
	}
	else {
		var thiselement = event.element();
		selectElement(thiselement);
	}
}

// flips the selected element
function flipSelected() {
	if (Object.isElement(selectedElement)) {
		var ele = CreateDragElement(selectedElement, true, $(selectedElement).getStyle('top'), $(selectedElement).getStyle('left'));
		delHandle();
		selectElement(ele);
	}
}

function nudgeSelectedUp() {
	var px = parseInt(rtrim($(selectedElement).getStyle('top'), 'px'));
	$(selectedElement).setStyle({ 'top': (px - 1)+'px'});
	MarkOverlaps();
}

function nudgeSelectedDown() {
	var px = parseInt(rtrim($(selectedElement).getStyle('top'), 'px'));
	$(selectedElement).setStyle({ 'top': (px + 1)+'px'});
	MarkOverlaps();
}

function nudgeSelectedLeft() {
	var px = parseInt(rtrim($(selectedElement).getStyle('left'), 'px'));
	$(selectedElement).setStyle({ 'left': (px - 1)+'px'});
	MarkOverlaps();
}

function nudgeSelectedRight() {
	var px = parseInt(rtrim($(selectedElement).getStyle('left'), 'px'));
	$(selectedElement).setStyle({ 'left': (px + 1)+'px'});
	MarkOverlaps();
}

//module menus sliding stuff
function activateMenu(thismenu){
	if(ActiveMenu != thismenu){
		if(ActiveMenu){	//close the last menu
			new Effect.SlideUp(ActiveMenu, {duration:MenuSpeed});
		}
		//slide open the passed in one
		setTimeout(function(){ new Effect.SlideDown(thismenu, {duration:MenuSpeed})},MenuSpeed * 1000);
		ActiveMenu = thismenu;
	}
}

//swapping out enclosures
function swapEnclosure(enc_number){
	//first remove the highlighting from the enclosure selector
	$(ActiveEnclosure).removeClassName('selectedenclosure');
	//remove the enclosure style from the main enclosure
	$('enclosure').removeClassName(ActiveEnclosureStyle);
	//hide all cover selectors
	$('cover-selector-sae14').hide();
	$('cover-selector-sae21').hide();
	$('cover-selector-sae28').hide();
	$('cover-selector-sae42').hide();
	//now add the correct styles	
	switch(enc_number){
		case 1: $('enclosure').addClassName('sae14'); //main enclosure
				$('enclosure-sae14').addClassName('selectedenclosure'); //selector highlighting
				ActiveEnclosure = 'enclosure-sae14'; //track enclosure
				ActiveEnclosureStyle = 'sae14'; //track style
				$('plug_img2').hide();
				$('cover-selector-sae14').show();
				swapCover('SAE-14PC');
			break;
		case 2: $('enclosure').addClassName('sae21');
				$('enclosure-sae21').addClassName('selectedenclosure');
				ActiveEnclosure = 'enclosure-sae21';
				ActiveEnclosureStyle = 'sae21';
				$('plug_img2').show();
				$('cover-selector-sae21').show();
				swapCover('SAE-21PC');
			break;
		case 3: $('enclosure').addClassName('sae28');
				$('enclosure-sae28').addClassName('selectedenclosure');
				ActiveEnclosure = 'enclosure-sae28';
				ActiveEnclosureStyle = 'sae28';
				$('plug_img2').show();
				$('cover-selector-sae28').show();
				swapCover('SAE-28PC');
			break;
		default: $('enclosure').addClassName('sae42');
				$('enclosure-sae42').addClassName('selectedenclosure');
				ActiveEnclosure = 'enclosure-sae42';
				ActiveEnclosureStyle = 'sae42';
				$('plug_img2').show();
				$('cover-selector-sae42').show();
				swapCover('SAE-42PC');
			break;
	}
	MarkOverlaps(); //run checks, etc.
}

//swapping out enclosures
function swapCover(cover_number){
	//first remove the highlighting from the enclosure selector
	$(ActiveCover).removeClassName('selectedcover');
	$(cover_number).addClassName('selectedcover'); //selector highlighting
	ActiveCover = cover_number;
	CreateBill(); //update Bill of Materials
}

//indicate the number of plugs used, 2 available for small, 4 for SAE42
function MarkPlugs(){
	PlugsUsed = 0;
	for(var i = 0; i < ComponentTracker.length; i++){ 
		if($(ComponentTracker[i]).hasClassName('powered')) PlugsUsed++; 
	}
	if(PlugsAvailable.get(ActiveEnclosureStyle) < PlugsUsed) ErrorMessage('plugs'); 
	else { //output the correct graphic(s) for the two images
		var P1 = document.getElementById('plug_img1');
		var P2 = document.getElementById('plug_img2');
		switch(PlugsUsed){
			case 0:
				P1.src = '../configurator_images/plugs/plugs0.gif';
				if(PlugsAvailable.get(ActiveEnclosureStyle) > 2) P2.src = '../configurator_images/plugs/plugs0.gif';
				break;
			case 1:
				P1.src = '../configurator_images/plugs/plugs1.gif';
				if(PlugsAvailable.get(ActiveEnclosureStyle) > 2) P2.src = '../configurator_images/plugs/plugs0.gif';
				break;
			case 2:
				P1.src = '../configurator_images/plugs/plugs2.gif';
				if(PlugsAvailable.get(ActiveEnclosureStyle) > 2) P2.src = '../configurator_images/plugs/plugs0.gif';
				break;
			case 3:	
				P1.src = '../configurator_images/plugs/plugs2.gif';
				if(PlugsAvailable.get(ActiveEnclosureStyle) > 2) P2.src = '../configurator_images/plugs/plugs1.gif';
				break;
			default:
				P1.src = '../configurator_images/plugs/plugs2.gif';
				if(PlugsAvailable.get(ActiveEnclosureStyle) > 2) P2.src = '../configurator_images/plugs/plugs2.gif';
				break;
		}
	}		
}

function BOM(){
	var targetURL = 'bill_of_materials.php?';
	//append each module
	//alert(ComponentTracker.length);
	for(var i = 0; i < ComponentTracker.length; i++){ 
		targetURL += i + '=' + escape(ComponentTracker[i].id) + '&';
	}
	var enclosureout = ActiveCover;
	targetURL += 'enclosure=' + enclosureout + "&plugs=" + PlugsUsed;
	window.open(targetURL,'_blank');
}
/* onload */
onload = function() {
	//[delete] key listener
	
	var KeyActiondel = new YAHOO.util.KeyListener(document, { keys: [46,8] }, { fn:delHandle });
	KeyActiondel.enable();
	
	/*
	var KeyActionup = new YAHOO.util.KeyListener(document, { keys: 104 }, { fn:nudgeSelectedUp }); //104
	KeyActionup.enable();
	
	var KeyActiondown = new YAHOO.util.KeyListener(document, { keys: 98 }, { fn:nudgeSelectedDown }); //98
	KeyActiondown.enable();
	
	var KeyActionleft = new YAHOO.util.KeyListener(document, { keys: 100 }, { fn:nudgeSelectedLeft }); //100
	KeyActionleft.enable();
	
	var KeyActionright = new YAHOO.util.KeyListener(document, { keys: 102 }, { fn:nudgeSelectedRight }); //102
	KeyActionright.enable();
	*/
	
	//try{MM_preloadImages('/images/cart_top_r3_c5_f2.gif','/images/cart_top_r3_c7_f2.gif','/images/cart_top_r3_c9_f2.gif','/images/cart_top_r3_c11_f2.gif','/images/cart_top_r3_c14_f2.gif','/images/cart_top_r3_c18_f2.gif','/images/ternav_r1_c2_f2.gif','/images/ternav_r1_c4_f2.gif','/images/ternav_r1_c6_f2.gif','/images/cart_top_r1_c15_f2.gif')}catch(e){}
	//select initial stuff? (debug)
	//swapEnclosure(1);
	//swapCover(1);
	//initial black screen with directions?
	
	/*Droppables.add('trash', {
		accept: 'dragme',
		hoverclass: 'hover',
		onDrop: function(drag,drop,drop_event) {
			UnTrack(drag); //can't remove anything but selected
			drag.parentNode.removeChild(drag);
			MarkOverlaps()
		}
	});*/
	
}

function rtrim ( str, charlist ) {
    charlist = !charlist ? ' \\s\u00A0' : (charlist+'').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
    var re = new RegExp('[' + charlist + ']+$', 'g');
    return (str+'').replace(re, '');
}

function substr( f_string, f_start, f_length ) {
	f_string += '';
	
	if(f_start < 0) {
		f_start += f_string.length;
	}
	
	if(f_length == undefined) {
		f_length = f_string.length;
	} else if(f_length < 0){
		f_length += f_string.length;
	} else {
		f_length += f_start;
	}
	
	if(f_length < f_start) {
		f_length = f_start;
	}

	return f_string.substring(f_start, f_length);
}