
/*	---------------------------------------------------------------------------
	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.el.setStyle('overflow','hidden');
		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:		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.adopt(this.imgs);
	    this.container.adopt(this.el);
		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:		Modal([speed,maskColor,width,height,classPrefix,onHide,onShow,onStart]);
	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")
				onHide: event
				onShow: event
				onStart: event
	AUTHOR:		Ryan J. Salva, http:www.capitolmedia.com
	REVISED:	January 2008
*/

Modal = new Class({
	Implements: [Events, Options],
	options: {
		speed: 200,
		maskColor: '#000000',
		width: 400,
		height: 'auto',
		classPrefix: 'Modal',
		onHide: $empty,
		onShow: $empty,
		onStart: $empty
	},
	initialize: function(options) {
		this.setOptions(options);
		var classPrefix = this.options.classPrefix;
		this.mask = new Element('div', {
			'class':classPrefix+'Mask',
			'styles':{
				'position':'absolute',
				'top': 0,
				'left': 0,
				'opacity': 0,
				'height': (window.getHeight() > window.getScrollHeight()) ? window.getHeight() : window.getScrollHeight(),
				'width': '100%',
				'background':this.options.maskColor,
				'z-index': 9999
			}
		});
		this.pop = new Element('div',{
			'class':classPrefix+'Pop',
			'styles':{
				'position': 'absolute',
				'visibility': 'hidden',
				'width': '100%',
				'margin': 0,
				'z-index': 10000
			}
		});
		this.mask.set('tween',{duration:this.options.speed});
		this.pop.set('tween',{duration: this.options.speed});
		$$('body')[0].adopt(this.mask, this.pop);
		this.isShowing = false;

//		this.fireEvent('onStart');
	},
	show: function(el, title) {
		if (this.isShowing) return false;
		this.isShowing = true;
		var classPrefix = this.options.classPrefix;
		var container = new Element('div',{
			'class':classPrefix+'Container',
			'styles':{
				'margin':'0 auto',
				'width':this.options.width
			}
		});
		var message = new Element('div').addClass(classPrefix+'Message').adopt(el);
		var title = (title)?new Element('div',{'text':title,'className':classPrefix+'Title'}):null;
		var close = new Element('a', {
			'href':'#', 
			'text':'Close',
			'class':classPrefix+'Close',
			'events': {
				'click': function(e) {
					e.stop();
					this.hide();
				}.bind(this)
			}
		});
		$$('#Primary', '#Secondary').setStyle('display', 'none'); // custom for MRS
		$$('select').setStyle('visibility', 'hidden');
		
		container.adopt(close,title, message);
		this.pop.empty();
		this.pop.adopt(container);
		
		this.pop.setStyles({
			'top': window.getScroll().y - this.pop.getSize().y,
			'visibility':'visible'
		});
		window.addEvent('keydown', function(e) {
			if(e.key == 'esc') this.hide();
		}.bind(this));
		
		this.mask.tween('opacity',0.8);
		var slideTo = ((window.getSize().y - container.getSize().y) / 2 + window.getScroll().y);
		this.pop.tween('top',slideTo);
		this.periodical = this.update.periodical(100, this);
//		this.fireEvent('onShow');
	},
	update: function() {
		var slideTo = ((window.getSize().y - this.pop.getSize().y) / 2 + window.getScroll().y);
		this.pop.tween('top',slideTo);
		var h = (window.getSize().y > window.getScrollSize().y) ? window.getSize().y : window.getScrollSize().y;
		this.mask.setStyle('height', h);
	},
	hide: function() {
		$$('#Primary', '#Secondary').setStyle('display', 'block'); // custom for MRS
		$$('select').setStyle('visibility', 'visible');

		$clear(this.periodical);
		this.pop.empty();
		this.mask.tween('opacity',0);
		this.isShowing = false;
//		this.fireEvent('onHide');
	}
});



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

	ABOUT:		Creates tabbed property panels. Resulting HTML looks like this:
				<span class="PanelTab">First Tab</span>
				<span class="PanelTab">Second Tab</span>
				<div class="PanelContainer">
					<div class="Panel">
						Content displayed when you click on the first tab.
					</div>
					<div class="Panel">
						Content displayed when you click on the second tab.
					</div>
				</div>
*/

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);
	}
});


/*	---------------------------------------------------------------------------
	Script		: Validate
	Version		: 2.0
	Authors		: Samuel Birch
	Desc		: Form validation
	Licence		: Open Source MIT Licence
	
	Modified	: Ryan J. Salva
				: Updated to be compatible with Capitol Media code library
*/

var Validate = new Class({
	
	Implements: [Options,Events],
	options: {
		validateOnBlur: true,
		errorClass: 'error',
		errorMsgClass: 'errorMessage',
		dateFormat: 'MM/dd/yy',
		showErrorsInline: true,
		label: 'Please wait...',
		onFail: Class.empty,
		onSuccess: Class.empty
	},

	initialize: function(form, options) {
		this.setOptions(options);
		
		this.form = $(form);
		this.elements = this.form.getElements('.required, .email, .number, .date, .postcode');

		this.list = [];
		
		this.elements.each(function(el,i){
			if(this.options.validateOnBlur){
				el.addEvent('blur', this.validate.bind(this, el));
			}
		}.bind(this));
		
		this.form.addEvent('submit', function(e){
			var event = new Event(e);
			var doSubmit = true;
			this.elements.each(function(el,i){
				if(! this.validate(el)){
					event.stop();
					doSubmit = false
					this.list.include(el);
				}else{
					this.list.erase(el);
				}
			}.bind(this));
			
			if(doSubmit){
				if(this.options.onSuccess){
					event.stop();
					this.fireEvent('onSuccess');
				} else {
					this.form.getElement('input[type=submit]').setProperty('value',this.options.label);
				}
			}else{
				// this.getList();
				this.fireEvent('onFail');
			}
			
		}.bindWithEvent(this));
	},
	
	getList: function(){
		var list = new Element('ul');
		this.list.each(function(el,i){
			if(el.title != ''){
				var li = new Element('li').set('text',el.title);
			}
		});
		return list;
	},
	
	validate: function(el){
		var valid = true;
		this.clearMsg(el);
		
		switch(el.type){
			case 'text':
			case 'textarea':
				if(el.hasClass('required') && el.value == ''){
					valid = false;
					this.setMsg(el, 'This field is required.');
				} else {
					valid = true;
				}
				if (el.value != '') {
	
					if(el.hasClass('email')){
						var regEmail = /^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/;
						if(el.value.toUpperCase().match(regEmail)){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Enter a valid email address.');
						}
					}
					
					if(el.hasClass('number')){
						var regNum = /[-+]?[0-9]*\.?[0-9]+/;
						if(el.value.match(regNum)){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Enter a valid number');
						}
					}
					
					if(el.hasClass('postcode')){
						var regPC = /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$/
						if(el.value.match(regPC)){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Enter a valid postcode');
						}
					}
					
					if(el.hasClass('date')){
						var d = Date.parse(el.value);
						if(d != null){
							el.value = d.toString(this.options.dateFormat);
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Enter a valid date in the format: '+this.options.dateFormat.toLowerCase());
						}
					}
				}
					
				break;
				
			case 'select-one':
				if(el.hasClass('required') && el.selectedIndex != 0) {
					valid = true;
				} else {
					valid = false;
					this.setMsg(el, 'This field is required.');
				}
				break
					
			case 'checkbox':
				if(!el.checked){
					valid = false;
					this.setMsg(el);
				}else{
					valid = true;
				}
				break;
				
			case 'radio':
				var rad = $A(this.form[el.name]);
				var ok = false;
				rad.each(function(e,i){
					if(e.checked){
						ok = true;
					}
				});
				if(!ok){
					valid = false;
					this.setMsg(rad.getLast(), 'Please select an option');
				}else{
					valid = true;
					this.clearMsg(rad.getLast());
				}
				break;
				
		}
		return valid;
	},
	
	setMsg: function(el, msg){
		if(msg == undefined){
			msg = el.get('title');
		}
		if(this.options.showErrorsInline){
			if(el.error == undefined){
				var pos = el.getPosition(el.getOffsetParent());
				var width = el.getWidth();
				el.error = new Element('div',{
					'className':this.options.errorMsgClass,
					'styles':{
						opacity: 0,
						position: 'absolute',
						left: pos.x + width,
						top: pos.y
						},
					'text':msg
				});
				el.error.inject(el.getParent(),'inside');
				el.error.tween('opacity',1); 
			} else {
				el.error.set('text',msg);
			}
			el.addClass(this.options.errorClass);
		}
	},
	
	clearMsg: function(el){
		el.removeClass(this.options.errorClass);
		if(el.error != undefined){
			el.error.destroy();
			el.error = undefined;
		}
	}
	
});
