/*	---------------------------------------------------------------------------
	CLASS:		Layout(el[,columns])
	AUTHOR:		Ryan J. Salva, http://www.capitolmedia.com
	REVISED:	January 2008
	EXAMPLE:	<div id="Wrapper"><div id="Left">Foo</div><div id="Right">Bar</div></div>
				var x = new Layout('Wrapper',['Left','Right']);
	ABOUT:		Utility function designed to fix any layout using aboslute positioning for each column
				Adjusts the page to make wrapper as tall as the highest column (left, right, etc.)
				Most Capitol Media websites use the column ids: Left, Right, Middle and Canvas	
*/

var Layout = new Class({
	initialize: function(el,columns){
		this.columns = columns;
		this.el = $(el);
		if (!$defined(this.el)) return false;
		
		this.columns.each(function(col,index) {
			this.columns[index] = $(col);
		}.bind(this));
		this.columns = this.columns.clean();
		this.el.set('tween', {duration: 100});
		this.periodical = this.update.bind(this).periodical(200);
	},
	update: function() {
		var y = 0;
		this.columns.each(function(col,index) {
			var h = col.getCoordinates().height;
			if(h > y) y = h;
		});
		this.el.tween('height',y);
	}
});


/*	---------------------------------------------------------------------------
	CLASS:		Element
	METHOD:		fix();
	ABOUT:		Fixes alpha transparency in IE6
	REVISED:	February 27, 2008
*/

Element.implement({
	fix: function(){
		if(!Browser.Engine.trident) return this;
		var src;
		var size = this.getSize();
		if(this.get('tag')=='img'){
			src = this.get('src');
			if(src.indexOf('.png') < 0) return this;
			this.set('src', '/site/x.gif');
		} else {
			var bg = this.getStyle('background-image');
			if(bg && bg!='none')
				src = bg.match(/\(([^)]+)\)/)[1];
			if(src.indexOf('.png') < 0) return this;
		}
		if (src) {
			if(this.getStyle('display')=='inline' && !['input', 'textarea', 'button'].contains(this.get('tag'))) {
				this.setStyles({
					'display': 'block',
					'width': size.x,
					'height': size.y
				});
			}
			this.setStyles({
				'background': '',
				'filter': 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled="true", src="'+src+'", sizingMethod="crop")'
			});
		}
		return this;
	}
});
if(Browser.Engine.trident4) window.addEvent('domready', function() {
	$$('img[src$=png]').fix();
});


/*	---------------------------------------------------------------------------
	CLASS:		Menu();
	AUTHOR:		Ryan J. Salva
	REVISED:	December 2007

	Creates a drop-down menu for navigation. Also Corrects Windows IE support 
	for LI:hover and adds an <IFRAME> behind drop-down menus to keep the 
	menu above <select> elements.
*/

var Menu = new Class({
	Implements: Options,
	options: {
		iframe: false,
		onComplete: Class.empty,
		onStart: Class.empty
	},
	initialize: function(el,options){
		this.el = $(el);
		if (!$defined(this.el)) return false;
		this.setOptions(options);
		
		this.el.getElements('li').each(function(li,index) {
			li.addEvent('mouseenter',function() {
				this.addClass('hover');
			});
			li.addEvent('mouseleave',function() {
				this.removeClass('hover');
			});
		});
		if (this.options.iframe) this.addIframe();
	},
	addIframe: function() {
		this.el.getElements('ul').each(function(ul,index) {
			var coord = ul.getCoordinates();
			var iframe = new Element('iframe',{'src':'about:blank','styles':{
				overflow:'hidden',
				border:0,
				width: coord.width,
				height: coord.height,
				left: 0,
				top: 0,
				zIndex: -10,
				opacity: 0
			}});
			iframe.injectTop(ul);
			ul.setStyle('z-index',99);
		});
	}
});




/*	---------------------------------------------------------------------------
	CLASS:		Fader(container,[pause,duration,loop])
	AUTHOR:		Ryan J. Salva
	MODIFIED: December 22, 2007
 
	creates a single, rotating image on a page

	IMPLEMENTATION:
	<div id="Container">
		<img src="1.jpg" /><img src="2.jpg" /><img src="3.gif" />
	</div>
	<script type="text/javascript">
		window.addEvent('domready',function() { 
			var f = new Fader('Container');
			f.start();
		});
	</script>
*/

var Fader = new Class({
	Implements: Options,
	options: {
		pause: 5000,
		duration: 1000,
		loop: true
	},
	initialize: function(container,options) {
		this.setOptions(options);
		this.container = $(container);
		this.imgs = this.container.getElements('img');
		this.imgs.setStyles({
			'position':'absolute',
			'top':0,
			'left':0,
			'opacity':0
		});
		this.imgs[0].setStyle('opacity',1);
		this.el = new Element('div',{'styles': {
			'position':'relative'
	    }});
	    this.el.injectInside(this.container);
	    this.el.adopt(this.imgs);
		this.next = 0;
		this.start();
	},
	start: function() {
		this.show();
		this.periodical = this.show.bind(this).periodical(this.options.pause);
	},
	stop: function() {
		$clear(this.periodical);
	},
	show: function() {
		if (!this.options.loop && this.next==this.imgs.length-1) this.stop();
		this.next = (this.next==this.imgs.length-1)?0:this.next+1;
		var prev = (this.next==0)?this.imgs.length-1:this.next-1;
		
		this.imgs[this.next].fade('in');
		this.imgs[prev].fade('out');
	}
});


/*	---------------------------------------------------------------------------
	CLASS:		Counter(el);
	AUTHOR:		Ryan J. Salva, http:www.capitolmedia.com
	REVISED:	January 2008

	Places a counter on the page displaying the number of remaining characters 
	in a form element
	
	IMPLEMENTATION:
	
	<span id="target"></span>
	<textarea id="myText"></textarea>
	
	<script language="javascript">
		var counter = new Counter('myText',{'counter':'target','maxlength':1000});
	</script>
*/

var Counter = new Class({
	Implements: Options,
	options: {
		counter: null,
		maxlength: 500,
		onComplete: Class.empty,
		onStart: Class.empty
	},
	initialize: function(el,options){
		this.setOptions(options);
		this.el = $(el);
		this.max = ($defined(this.el.getAttribute('maxlength')))?this.el.getAttribute:this.options.maxlength;
		this.len = this.el.value.length;
		
		if ($defined(this.options.counter)) {
			this.counter = $(this.options.counter);
		} else {
			this.counter = new Element('span');
			this.counter.inject(this.el,'after');
		}
		this.counter.setText(this.max - this.len);
		this.el.addEvent('keyup',this.update.bind(this));
	},
	update: function(e) {
		this.len = this.el.value.length;
		this.counter.setText(this.max - this.len);
		if (this.len >= this.max) {
			this.el.value = this.el.value.substring(0,this.max - 1);
			if (this.el.createTextRange) {
				var range = this.el.createTextRange();
				range.collapse(false);
				range.select();
			}
			this.el.scrollTop = this.el.scrollHeight;
		}
	}
});


/*	---------------------------------------------------------------------------
	CLASS:		Modal([options]);
	OPTIONS:	speed:				the transition speed (default:500)
				maskColor:			the background color of the mask (default: black)
				width:				default width of the dialog box (default:400px)
				height:				default height of the dialog box (default: auto)
				classPrefix:		used to define unique classes for each dialog box (default: "Modal")
	EVENTS:		onHide				fires when closing the Modal box
				onShow				fires when showing the Modal box
				onStart				fires when first initializing the Modal box
				onStep				fires when stepping next or previous in a series
				onUpdate			fires when the window resizes
	AUTHOR:		Ryan J. Salva, http:www.capitolmedia.com
	REVISED:	August 22, 2009
*/
 
Modal = new Class({
	Implements: [Events, Options],
	options: {
		'speed': 500,
		'maskColor': '#04143F',
		'maskOpacity': .3,
		'width': 460,
		'height': '100%',
		'classPrefix': 'modal',
		'onHide': $empty,
		'onShow': $empty,
		'onStart': $empty,
		'onStep': $empty,
		'onUpdate': $empty
	},
	initialize: function(options) {
		this.setOptions(options);
		this.el = null;
		this.series = null;
		
		this.iframe = new Element('iframe',{
			'src': 'javascript:void(0);',
			'frameborder': 0,
			'scrolling': 'no',
			'styles':{
				'position': 'absolute',
				'top': 0,
				'left': 0,
				'width': '100%',
				'height': '100%',
				'opacity': 0
			}
		});
 
		this.mask = new Element('div', {
			'class':this.options.classPrefix+'Mask',
			'styles':{
				'position':'absolute',
				'top': 0,
				'left': 0,
				'opacity': 0,
				'width': '100%',
				'background':this.options.maskColor,
				'z-index': 9999
			},
			'events':{
				'click':function(e) {
					this.hide();
				}.bind(this)
			},
			'tween':{
				'duration':this.options.speed
			}
		});
 
		this.container = new Element('div',{
			'class':this.options.classPrefix+'Container',
			'styles':{
				'position': 'absolute',
				'visibility': 'hidden',
				'width': '100%',
				'margin': 0,
				'z-index': 10000
			},
			'events':{
				'click':function(e) {
					this.hide();
				}.bind(this)
			},
			'tween':{
				'duration': this.options.speed
			}
		});
		
		this.box = new Element('div',{
			'class':this.options.classPrefix+'Box',
			'styles':{
				'margin':'0 auto',
				'width': this.options.width,
				'height':this.options.height
			},
			'events': {
				'click': function(e) {
					e.stopPropagation();
				}
			},
			'morph': {
				'duration':this.options.speed
			}
		});
 
		this.message = new Element('div',{
			'class':this.options.classPrefix+'Message',
			'morph':{
				'duration':this.options.speed
			}
		});
 
		this.close = new Element('a', {
			'href':'#', 
			'text':'Close',
			'class':this.options.classPrefix+'Close',
			'events': {
				'click': function(e) {
					e.stop();
					this.hide();
				}.bind(this)
			}
		});
		
		this.next = new Element('a', {
			'href':'#',
			'text':'Next',
			'class':this.options.classPrefix+'Next',
			'events': {
				'click': function(e) {
					e.stop();
					this.step(1);
				}.bind(this)
			}
		});
		
		this.previous = new Element('a', {
			'href':'#',
			'text':'Previous',
			'class':this.options.classPrefix+'Previous',
			'events': {
				'click': function(e) {
					e.stop();
					this.step(-1);
				}.bind(this)
			}
		});
		
		this.controls = Element('div',{
			'class': 'modalControls',
			'styles':{
				'width': '100%'
			}
		});
 
		// build our DOM
		this.mask.adopt(this.iframe);
		this.container.adopt(this.box)
		this.box.adopt(this.message, this.close);
		
		// close the modal on esc, backspace, delete, space or enter
		window.top.addEvent('keydown', function(e) {
			if(this.el && (e.key == 'esc' || e.key == 'backspace' || e.key == 'delete' || e.key == 'space' || e.key == 'enter')) {
				e.stop();
				this.hide();
			}
		}.bind(this));
 
		// step previous on left or up arrow
		window.top.addEvent('keydown', function(e) {
			if(this.el && (e.key == 'left' || e.key == 'up')) {
				e.stop();
				this.step(-1);
			}
		}.bind(this));
 
		// step next on right or down arrow
		window.top.addEvent('keydown', function(e) {
			if(this.el && (e.key == 'right' || e.key == 'down')) {
				e.stop();
				this.step(1);
			}
		}.bind(this));
		
		window.top.addEvent('resize',function(e) {
			if (this.el) this.update();
		}.bind(this));
		
		this.fireEvent('onStart');
	},
	
	show: function(obj,series) {

		this.state = (this.el)?'load':'mask';
		
		// if nothing is showing, we need to set-up the mask, et al
		if (this.el) {
			this.el.dispose();
		} else {
			// setup our styles before going visible
			this.mask.setStyles({
				'opacity':0,
				'height': $(window).getScrollSize().y
			});
	 
			this.container.setStyles({
				'opacity':0,
				'top': $(window).getScroll().y + 100,
				'visibility':'visible'
			});
			
			this.box.setStyles({
				'width':this.options.width,
				'height':this.options.height
			});
			
			this.message.setStyles({
				'opacity':0
			});
			
			// add our mask and container to the DOM
			document.body.appendChild(this.mask);
			document.body.appendChild(this.container);
		}
		
		// if we're showing a series of items, we have a few extra steps
		if (series && $type(series) == 'array') {
			
			// make sure we have one long list
			this.series = series.flatten();
 
			// display next/previous buttons
			this.box.adopt(this.controls, this.next, this.previous);
 
			// find the current element in the series
			this.index = this.series.indexOf(obj);
 
			// if the element can't be found, put it at the end
			if (this.index < 0) this.series.include(obj);
		} else {
			this.series = null;
		}
		
		// animate into view
		this.animate(obj);
		
		// fire the show event
		this.fireEvent('onShow');
	},
	
	animate: function(obj) {
		this.timer = $clear(this.timer);
		
		// mask > load > resize > show > hide > load > resize > show > (repeat)
		switch (this.state) {
			case 'mask':
				// animate the dialog box into view
				this.mask.tween('opacity',this.options.maskOpacity);
				this.container.tween('opacity',1);
				this.state = 'load';
				this.timer = this.animate.delay(this.options.speed,this,obj);
				break;
			case 'load':
				switch($type(obj)) {
					case 'array':
						this.series = obj;
						this.animate(this.series[0]); // pluck the first element in the array and attempt to load it
						return null;
					case 'element':
						this.state = 'resize';
						this.animate(obj);
						return null;
					case 'string':
						obj = new Element('div',{'html':obj,'styles':{'width':this.options.width,'height':this.options.height}});
						this.state = 'resize';
						this.animate(obj);
						return null;
					case 'object':
						try {
							obj.send();
						} catch (error) {
							this.animate('Invalid request.');
						}
						return null;
					default:
						return false;
						break;
				}
				break;
 
			case 'resize':
				if (this.el) this.el.dispose();
 
				// temporarily add obj to the DOM so we can determine size
				obj.setStyles({
					'opacity':0,
					'visibility':'hidden',
					'position':'absolute',
					'top':0,
					'left':0
				});
				document.body.appendChild(obj);
				var size = obj.getSize();
				
				// resize the box to the dimensions of the new element
				this.box.morph({'width':size.x,'height':size.y});
				this.state = 'show';
				this.timer = this.animate.delay(this.options.speed,this,obj);
				break;
 
			case 'show':
				this.el = obj;
				this.el.setStyles({
					'opacity':1,
					'position':'static',
					'visibility':'visible'
				});
				this.message.adopt(this.el);
				this.message.morph({'opacity':1});
				this.state = null;
				break;
 
			case 'hide':
				this.message.morph({'opacity':0});
				this.state = 'load';
				this.timer = this.animate.delay(this.options.speed,this,obj);
				break;
 
			default:
				break;
		}
	},
	
	step: function(steps) {
 
		// only continue if we're in a series of elements
		if (!this.series || this.series.length <= 0) return false;
		
		this.index = this.index + steps;
		if (this.index < 0) this.index = this.series.length -1;
		if (this.index >= this.series.length) this.index = 0
 
		// which element do we display next?
		var obj = this.series[this.index];
		
		// if the element doesn't exist, abort mission
		if (!obj) return false;
		
		this.state = 'hide';
		this.animate(obj);
		this.fireEvent('onStep');
	},
 
	update: function() {
		this.mask.setStyle('height',$(window).getScrollSize().y);
		this.fireEvent('onUpdate');
	},
 
	hide: function() {

		 // take elements out of the DOM so we can reuse them next time
		this.container.dispose();
		this.next.dispose();
		this.previous.dispose();
		this.el.dispose();
		this.el = null;
 
		// return everything to normal
		this.state = null;
		this.series = null;
		this.timer = $clear(this.timer);
		this.mask.fade('out');
		this.fireEvent('onHide');
	}
});

/*	---------------------------------------------------------------------------
	CLASS:		Ticker(el,[speed,delay,direction]);
	OPTIONS:	speed:		the transition speed (default:500)
				delay:		the amount of time a news item stays at a position (default: 5000)
				direction:	horizontal or vertical scrolling (default: 'vertical')
	AUTHOR:		Ryan J. Salva
	EMAIL		ryan at capitolmedia.com
	REVISED:	September 2008
*/

var Ticker = new Class({
	Implements: Options,
	options: {
		speed: 1000,
		delay: 5000,
		direction: 'vertical'
	},
	initialize: function(el,options){
		this.setOptions(options);
		this.el = $(el);
		this.items = this.el.getElements('li');
		var w = 0;
		var h = 0;
		if(this.options.direction.toLowerCase()=='horizontal') {
			h = this.el.getCoordinates().height;
			this.items.each(function(li,index) {
				w += li.getCoordinates().width;
			});
		} else {
			w = this.el.getCoordinates().width;
			this.items.each(function(li,index) {
				h += li.getCoordinates().width;
			});
		}
		this.el.setStyles({
			position: 'absolute',
			top: 0,
			left: 0,
			width: w,
			height: h
		});
		this.fx = new Fx.Morph(this.el,{duration:this.options.speed,onComplete:function() {
			var i = (this.current==0)?this.items.length:this.current;
			this.items[i-1].injectInside(this.el);
			this.el.setStyles({
				left:0,
				top:0
			});
		}.bind(this)});
		this.current = 0;
		this.next();
	},
	next: function() {
		this.current++;
		if (this.current >= this.items.length) this.current = 0;
		var pos = this.items[this.current];
		this.fx.start({
			top: -pos.offsetTop,
			left: -pos.offsetLeft
		});
		this.next.bind(this).delay(this.options.delay+this.options.speed);
	}
});


/*	---------------------------------------------------------------------------
	CLASS:		Tabs(panels,[classPrefix])
	AUTHOR:		Ryan J. Salva, ryan@capitolmedia.com

	ABOUT:		Creates tabbed property panels
*/

var Tabs = new Class({
	Implements: Options,
	options: {
		classPrefix: 'Panel'
	},
	initialize: function(panels, options) {
		this.setOptions(options);
		if (panels.length <= 0) return false;
		
		this.panels = panels;
		this.panels.setStyle('display','none');
		
		this.tabs = [];
		this.panels.each(function(el,index) {
			var tab = new Element('span',{
				'class':this.options.classPrefix+'Tab',
				'text':el.get('title'),
				'events':{
					'click':function(e){
						e.stop();
						this.activate(el,e.target);
					}.bindWithEvent(this)
				}
			});
			this.tabs.include(tab);
		}.bind(this));
		
		this.container = new Element('div',{
			'class':this.options.classPrefix+'Container',
			'styles':{
				'overflow':'hidden',
				'height':0
			}
		});
		this.container.inject(this.panels[0],'before');
		this.panels.each(function(el,index) {
			this.container.adopt(el);
		}.bind(this));
		
		this.tabs.each(function(el,index){
			el.inject(this.container,'before');
		}.bind(this));
		
		this.activate(this.panels[0],this.tabs[0])

		
	},
	
	activate: function(panel,tab){
		this.panels.removeClass(this.options.classPrefix+'Active');
		panel.addClass(this.options.classPrefix+'Active');
		
		this.panels.setStyle('display','none');
		panel.setStyle('display','block');
		
		this.tabs.each(function(el,index){
			el.removeClass(this.options.classPrefix+'Active');
		}.bind(this));
		tab.addClass(this.options.classPrefix+'Active');
		
		this.container.tween('height',panel.getSize().y);
	}
});


// ------------------------------------------------------------------
// AUTHOR: Ryan J. Salva
// MODIFIED: May 23, 2005
// 
// DESCRIPTION:
// calculates number of gallons per square feet for GacoShield
// 1 gallon for every 100 square feet
// 1 five gallon bucket for every 500 square feet
// 1 gallon for every 12 linear feet of railing
//
// IMPLEMENTATION:
// <input type="text" onkeyup="howMuchGacoShield(this.value);" /> 
// <p id="HowManyKits"></p>

function howMuchGacoShield() {
	var sqft = document.getElementById("DeckSize").value;
	var lnft = document.getElementById("RailingSize").value;
	var bkt_base = (sqft/500) + (lnft/60);
	var bkt_kits = Math.floor(bkt_base);
	var bkt_extra = 0;
	var bkt_remainder = bkt_base - bkt_kits;
	if (bkt_remainder > 0 && bkt_remainder <= .2) bkt_extra = 1; 
	if (bkt_remainder > .2 && bkt_remainder <= .4) bkt_extra = 2;
	if (bkt_remainder > .4 && bkt_remainder <= .6) bkt_extra = 3;
	if (bkt_remainder > .6 && bkt_remainder <= .8) bkt_extra = 4;
	if (bkt_remainder > .8) bkt_kits++;

	document.getElementById("HowManyKits").innerHTML = bkt_kits + " Five Gallon Pails";
	document.getElementById("HowManyGallons").innerHTML = bkt_extra + " One Gallon Cans";
	return true;

}



	// ------------------------------------------------------------------
	// AUTHOR: Ryan J. Salva
	// MODIFIED: May 23, 2005
	// 
	// DESCRIPTION:
	// calculates number of kits, extra gallons and walnuts per square feet for GacoDeck Kit
	// 1 kit for every 100 square feet, plus...
	// 1 gallon for every 25 additional square feet between 1-50
	// 1 additional kit for 50+ additional square feet
	// additional walnuts if the number isn't divisible by 100
	//
	// IMPLEMENTATION:
	// <input type="text" onkeyup="howMuchGacoDeck(this.value);" /> 
	// <p id="HowManyKits"></p>
	// <p id="HowManyGallons"></p>
	// <p id="HowManyWalnuts"></p>
	
	function howMuchGacoDeck(v) {
		var bkt_base = v/100;
		var bkt_kits = Math.floor(bkt_base);
		var bkt_extra = 0;
		var bkt_nuts = 0;
		var bkt_tape = 0;
		var bkt_remainder = bkt_base - bkt_kits;
		if (bkt_remainder > .1 && bkt_remainder <= .3) bkt_extra = 1; 
		if (bkt_remainder > .3 && bkt_remainder <= .6) { bkt_extra = 2; bkt_nuts = 1; }
		if (bkt_remainder > .6) { bkt_kits += 1; bkt_remainder=0; }
		if (v <= 30) { bkt_extra = 1; bkt_nuts = 1; }
		if (v > 30 && v <= 60) bkt_tape = 1;
	
		document.getElementById("HowManyKits").innerHTML = bkt_kits + " Kits";
		document.getElementById("HowManyGallons").innerHTML = bkt_extra + " Extra Gallons";
		document.getElementById("HowManyWalnuts").innerHTML = bkt_nuts + " Extra GacoGrip Texture Granules";
		document.getElementById("HowManyTape").innerHTML = bkt_tape + " Extra Rolls of GacoDeck Tape";

	}

// ------------------------------------------------------------------
// AUTHOR: Ryan J. Salva
// MODIFIED: May 23, 2005
// 
// DESCRIPTION:
// calculates number of gallons per square feet for GacoRoof
// 1 gallon for every 50 feet
//
// IMPLEMENTATION:
// <input type="text" onkeyup="howMuchGacoRoof(this.value);" /> 
// <p id="HowManyKits"></p>

function howMuchGacoRoof(v) {
	var bkt_gallons = 0;
	var bkt_base = v/250;
	var bkt_pales = Math.floor(bkt_base);
	var bkt_remainder = bkt_base - bkt_pales;
	if (bkt_remainder > 0) {
        var bkt_leftover = Math.ceil((bkt_remainder*250)/50);

        if (bkt_leftover == 5){
        bkt_pales = bkt_pales + 1;
        bkt_gallons = 0;
        } else {

        bkt_gallons = bkt_leftover;
        }
        }
	document.getElementById("HowManyPales").innerHTML = bkt_pales + " Five Gallon Pails";
	document.getElementById("HowManyGallons").innerHTML = bkt_gallons + " One Gallon Cans"
}

// ------------------------------------------------------------------
// AUTHOR: Ryan J. Salva
// MODIFIED: May 23, 2005
// 
// DESCRIPTION: Submit's dealerlookup form.
//
function findProduct() {
	var sa = document.getElementById("SubmitAction").value;
	document.forms["DealerLookupGeneral"].action = sa;
	return true;
}