//	---------------------------------------------------------------------------
//	Script: string.cnet.js
//	These are mootools authored extensions designed to allow prototype.lite libraries run in this environment.
//	
//	Dependancies:
//	mootools - <Moo.js>, <String.js>, <Array.js>
//	
//	Author:
//	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>
//	
//	Class: String
//	This extends the <String> prototype.

String.implement({
	stripTags: function() {
		return this.replace(/<\/?[^>]+>/gi, '');
	},
	stripScripts: function() {
		return this.replace(/<script[^>]*?>.*?<\/script>/img, '');
	},
	evalScripts: function() {
		var scripts = this.match(/<script[^>]*?>.*?<\/script>/g);
		if(scripts) scripts.each(function(script){
			eval(script.replace(/^<script[^>]*?>/, '').replace(/<\/script>$/, ''));
		});
	},
	replaceAll: function(searchValue, replaceValue, regExOptions) {
		return this.replace(new RegExp(searchValue, $pick(regExOptions,'gi')), replaceValue);
	},
	urlEncode: function() {
		if (this.indexOf('%') > -1) return this;
		else return escape(this);
	},
	parseQuery: function() {
		var vars = this.split(/[&;]/);
		var rs = {};
		if (vars.length) vars.each(function(val) {
			var keys = val.split('=');
			if (keys.length && keys.length == 2) rs[encodeURIComponent(keys[0])] = encodeURIComponent(keys[1]);
		});
		return rs;
	},
	tidy: function() {
		var txt = this.toString();
		$each({
			"[\xa0\u2002\u2003\u2009]": " ",
			"\xb7": "*",
			"[\u2018\u2019]": "'",
			"[\u201c\u201d]": '"',
			"\u2026": "...",
			"\u2013": "-",
			"\u2014": "--"
		}, function(value, key){
			txt = txt.replace(new RegExp(key, 'g'), value);
		});
		return txt;
	}
});


//	---------------------------------------------------------------------------
//	CLASS:	Layout()
//	
//	LAST MODIFIED: 09/28/07
//	AUTHOR:	Ryan J. Salva
//
//	Utility function designed to fix any layout using aboslute positioning for column
//
//	IMPLEMENTATION:
//	The following code adjusts the page to make wrapper as tall as the highest column (left, right, etc.)
//	var x = new Layout('Wrapper',['Left','Right','Middle','Canvas']);
//	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.fx = new Fx.Tween(this.el,'height',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.fx.start(y);
	}
});


//	---------------------------------------------------------------------------
//	FUNCTION:	editMode()
//	LAST MODIFIED: 09/28/07
//	AUTHOR:	Ryan J. Salva
//
//	Used by the SUBTEXT control panel to import files/css/wysiwyg.css while in edit mode (e.g. ?edit=true)

function editMode() {
	var url = window.location.search.substring(1);
	var q = url.parseQuery();
	if ($defined(q.edit)) {
		new Asset.css('css/wysiwyg.css', {id: 'wysiwygCSS'});
		new Asset.javascript('js/mooeditable.js', {id: 'wysiwygJS'});
		window.addEvent('load', function(){
			var mooed = new MooEditable($$('.mooeditable'));
		});
	}
}
editMode();


//	---------------------------------------------------------------------------
//	FUNCTION:	fixPNG()
//	AUTHOR:		Ryan J. Salva
//
//	Enables transparecy for PNG files in IE
//	NOTE: Makes most colors a little darker than the GIF counterpart
//	
//	REQUIRED ASSETS:
//	files/site/x.gif (1x1 transparent GIF)

function fixPNG(){
	$$('img[src$=png]').each(function(el){
		var coord = el.getCoordinates();
		el.setStyles({
			width: coord.width,
			height: coord.height,
			filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + el.src + '", sizingMethod="scale")',
			visibility: 'hidden'
		});
		el.src = 'site/x.gif';
		el.addEvent('load',function() {
			el.setStyle('visibility','visible');
		});
	});
}
if(window.ie6) window.addEvent('domready', fixPNG);



//	---------------------------------------------------------------------------
//	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.
//
//	REQUIREMENTS:
//	Styles found in default.css
//	
//	TESTED IN:
//	Windows: IE 6, Firefox 1, Opera 8
//	Mac: IE 5.2, Firefox 1, Safari 1

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:		Ticker()
//	AUTHOR:		Ryan J. Salva
//	REVISED:	January 2008
//

var Ticker = new Class({
	Implements: Options,
	options: {
		speed: 1000,
		delay: 5000,
		direction: 'vertical',
		onComplete: Class.empty,
		onStart: Class.empty
	},
	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:		FormTip(selector,options)
//	AUTHOR:		Ryan J. Salva
//	REVISED:	December 2008

var FormTip = new Class({
	Implements: Options,
	options: {
		className: 'FormTip',
		onComplete: Class.empty,
		onStart: Class.empty
	},
	initialize: function(selector,options){
		this.setOptions(options);
		this.els = $$(selector);
		this.els.each(function(el,index){
			el.addEvent('focus',this.show.bindWithEvent(this));
			el.addEvent('blur',this.hide.bindWithEvent(this));
		}.bind(this));
	},
	show: function(e) {
		var e = new Event(e);
		var el = e.target;
		if ($type(el) != 'element') return false;
		var title = el.getAttribute('title');
		if (!$defined(title)) return false;
		var pos = el.getPosition(el.getOffsetParent());
		var width = el.getWidth();
		this.tip = new Element('div',{'class':this.options.className,'styles':{
			opacity: 0,
			position: 'absolute',
			left: pos.x + width,
			top: pos.y
		}}).setText(title);
		this.tip.inject(el.getParent(),'inside');
		this.tip.tween('opacity',1); 
	},
	hide: function() {
		this.tip.remove();
	}
});


// ------------------------------------------------------------------
//	AUTHOR: Ryan J. Salva
//	MODIFIED: December 22, 2007
// 
//	DESCRIPTION:
//	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,
		onComplete: Class.empty,
		onStart: Class.empty
	},
	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;
	},
	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) $clear(this.periodical);
		this.next = (this.next==this.imgs.length-1)?0:this.next+1;
		
		var appear = this.imgs[this.next].effect('opacity', {'duration': this.options.duration});
		appear.start(0,1);

		var prev = (this.next==0)?this.imgs.length-1:this.next-1;
		var disappear = this.imgs[prev].effect('opacity',{'duration':this.options.duration});
		disappear.start(1,0)
	}
});



//	---------------------------------------------------------------------------
//	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
//	
//	TESTED ON:
//	Windows Firefox 1, IE 6, Opera 8, Netscape 6
//	Mac Safari 1, IE 5.2
//
//	REQUIRED ASSETS:
//	HTML with <TEXTAREA ID="TextArea1" COUNTER="target" MAXLENGTH="650"></TEXTAREA> and <SPAN ID="target"></SPAN>
//
//	IMPLEMENTATION:
//	var c = new Counter('myTextarea',{'counter':'myCounter','maxlength':1000});

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:	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: Class.empty,
		onShow: Class.empty,
		onStart: Class.empty
	},
	initialize: function(options) {
		this.setOptions(options);
		this.isShowing = false;
		var classPrefix = this.options.classPrefix;
		this.mask = new Element('div', {'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
		}}).addClass(classPrefix+'Mask');
		this.pop = new Element('div',{'styles':{
			'position': 'absolute',
			'visibility': 'hidden',
			'width': '100%',
			'margin': 0,
			'z-index': 10000
		}}).addClass(classPrefix+'Pop');
		this.container = new Element('div',{'styles':{
			'margin':'0 auto'
		}}).addClass(classPrefix+'Container');
		this.close = new Element('div').adopt(new Element('a', {'href':'#', 'text':'Close'})).addClass(classPrefix+'Close');

		this.fade = new Fx.Tween(this.mask, 'opacity', {duration:this.options.speed});
		this.slide = new Fx.Tween(this.pop, 'top', {duration: this.options.speed});
		
		this.fireEvent('onStart');
	},
	show: function(el, title) {
		var classPrefix = this.options.classPrefix;
		switch($type(el)) {
			case 'element':
				this.el = new Element('div',{'styles':{'height':this.options.height}}).adopt(el.clone().cloneEvents(el));
				break;
			case 'string':
				this.el = new Element('div',{'styles':{'height':this.options.height}}).set('html', el);
				break;
			default:
				return false;
				break;
		}
		var message = new Element('div').addClass(classPrefix+'Message').adopt(this.el);
		if(title) var title = new Element('div').setText(title).addClass(classPrefix+'Title');
		
		if(this.isShowing) {
			this.container.adopt(title, message);
		} else {
			this.close.getElement('a').addEvent('click', function(event) {
				event.stop();
				this.hide();
			}.bind(this));
			window.addEvent('keydown', function(event) {
				if(event.key == 'esc') this.hide();
			}.bind(this));
			
			$$('object', 'select').setStyle('visibility', 'hidden');
			
			$$('body').adopt(this.mask, this.pop);
			this.container.adopt(this.close, title, message);
			this.container.inject(this.pop, 'inside').setStyle('width', this.options.width);
		}
		
		this.pop.setStyles({
			'top': window.getScroll().y - this.pop.getSize().y,
			'visibility':'visible'
		});

		this.fade.start(0.8);
		var slideTo = ((window.getSize().y - this.container.getSize().y) / 2 + window.getScroll().y);
		this.slide.start(slideTo);
		this.periodical = this.update.periodical(100, this);
		this.isShowing = true;
		this.fireEvent('onShow');
	},
	update: function() {
		var slideTo = ((window.getSize().y - this.container.getSize().y) / 2 + window.getScroll().y);
		this.slide.start(slideTo);
		var h = (window.getSize().y > window.getScrollSize().y) ? window.getSize().y : window.getScrollSize().y;
		this.mask.setStyle('height', h);
	},
	hide: function() {
		$$('object', 'select').setStyle('visibility', 'visible');
		$clear(this.periodical);
		this.slide.cancel();
		var slideTo = window.getScroll().y - this.pop.getSize().y;
		this.slide.start(slideTo).chain(function() {
			this.pop.destroy();
			this.fade.start(0).chain(function() {
				this.mask.remove();
				this.isShowing = false;
				this.fireEvent('onHide');
			}.bind(this));
		}.bind(this));
	}
});


// -------------------------------------------------
//	AUTHOR: Ryan J. Salva
//	LAST MODIFIED: 12/28/07
//
//	Creates a kind of image gallery with thumbnail images and a single, full-size image


var Carousel = new Class({
	Implements: Options,
	options: {
		thumbSelector: 'a.Thumbnail',
		imageClass:'CarouselImage',
		onComplete: Class.empty,
		onStart: Class.empty
	},
	initialize: function(el,options) {
		this.setOptions(options);
		this.el = $(el);
		this.el.setStyles({
			overflow:'hidden',
			position:'relative'
		});
		this.thumbs = $$(this.options.thumbSelector);
		this.fx = new Fx.Morph(this.el, { 'duration': 250 });
		var crsl = this;
		
		this.thumbs.each(function(anchor,index) {
			anchor.addEvent('click',function(e) {
				var e = new Event(e);
				e.stop();
				this.loadImage(anchor.href,'Carousel'+index);
				this.thumbs.removeClass('Active');
				anchor.addClass('Active');
			}.bind(this));
		}.bind(this));
		this.loadImage(this.thumbs[0].href,'Carousel0');
	},
	loadImage: function(src,id) {
		this.fx.cancel();
		this.fx.start({
			opacity:0
		}).chain(function() {
			this.el.getElements('img').setStyle('opacity',0);
			if($(id)) {
				// show it right away
				this.showImage($(id))
			} else {
				// load and add it to the DOM first
				var img = new Element('img',{'src':src,'id':id,'class':this.options.imageClass,'styles':{
					position: 'absolute',
					top: 0,
					left: 0
				}});
				img.addEvent('load',function() {
					img.injectInside(this.el);
					this.showImage(img);
				}.bind(this));
			}
		}.bind(this));
	},
	showImage: function(img) {
		img.setStyle('opacity',1);
		var coord = img.getCoordinates();
		this.fx.start({
			'height':coord.height,
			'width':coord.width
		}).chain(function(){
			this.start({
				opacity:1
			});
		});
	}
});

// -------------------------------------------------
//	AUTHOR: Unknown
//	LAST MODIFIED: 12/28/07
//
//	Gives an element gravity

var Physics = new Class({
	Implements: Options,
	options: {
		onComplete: Class,
		onStart: Class,
		onStep: Class,
		gravity: 1,
		restitution: 0.6,
		friction: 0.9,
		unit: 'px',
		fps: 30
	},
	
	initialize: function(el, container, options){
		this.setOptions(options);
		this.el = $(el);
		this.container = $(container);
		
		this.velocity = {
			x: 0,
			y: 0
		};
		
		this.position = {};
		this.oldPosition = {};
		
		this.oldVelocity = {};
		
		this.position.x = this.oldPosition.x = this.el.offsetLeft;
		this.position.y = this.oldPosition.y = this.el.offsetTop;
		
		var phys = this;
		
		this.dragger = new Drag.Move(this.el, {
			
			snap: false,
			
			onDrag: function(){
				phys.dragging = true;
				
				if (phys.position.y + phys.el.offsetHeight > phys.container.offsetHeight){ //touches bottom
					phys.stopDrag();
				}
				if (phys.position.y < 0){ //touches top
					phys.stopDrag();
				}
				if (phys.position.x + phys.el.offsetWidth > phys.container.offsetWidth){ //touches right
					phys.stopDrag();
				}
				if (phys.position.x < 0){ //touches left
					phys.stopDrag();
				}
			},
			
			onComplete: function(){
				phys.dragging = false;
			}
		});
	},
	
	stopDrag: function(){
		this.dragging = false;
		this.dragger.stop();
	},
	
	step: function(){
		
		this.oldPosition.x = this.position.x;
		this.oldPosition.y = this.position.y;
		
		if (!this.dragging){
			
			this.options.onStep.call(this);
		
			this.velocity.y += this.options.gravity;
		
			this.position.x += this.velocity.x;
			this.position.y += this.velocity.y;
			
			var isOnGround = false;
		
			if (this.position.y + this.el.offsetHeight > this.container.offsetHeight){ //touches bottom
				this.position.y = this.container.offsetHeight - this.el.offsetHeight;
				this.velocity.y *= -this.options.restitution;
				if (!this.options.airFriction) this.velocity.x *= this.options.friction;
				
				isOnGround = true;
			}
			
			if (isOnGround) {
				this.isOnGround = true;
				if (this.el.onGround) this.el.onGround();
			}
			else {
				if (this.el.onAir) this.el.onAir();
				this.isOnGround = false;
			}
		
			if (this.position.y < 0){ //touches top
				this.position.y = 0;
				this.velocity.y *= -this.options.restitution;
				
				this.isOnTop = true;
			} else {
				this.isOnTop = false;
			}
		
			if (this.position.x + this.el.offsetWidth > this.container.offsetWidth){ //touches right
				this.position.x = this.container.offsetWidth - this.el.offsetWidth;
				this.velocity.x *= -this.options.restitution;
				this.isOnRight = true;
			} else {
				this.isOnRight = false;
			}
		
			if (this.position.x < 0){ //touches left
				this.position.x = 0;
				this.velocity.x *= -this.options.restitution;
				
				this.isOnLeft = true;
			} else {
				this.isOnLeft = false;
			}
			
			if (this.options.airFriction){
				this.velocity.y *= this.options.friction;
				this.velocity.x *= this.options.friction;
			}
			
			this.el.setStyle('left', this.position.x+'px');
			this.el.setStyle('top', this.position.y+'px');
		
		} else {
			this.position.x = this.el.style.left.toInt();
			this.position.y = this.el.style.top.toInt();
			this.velocity.x = ( this.position.x - this.oldPosition.x ) / 2;
			this.velocity.y = ( this.position.y - this.oldPosition.y ) / 2;
		}
		
	},
	
	start: function(){
		this.options.onStart.pass(this.el, this).delay(10);
		this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
		return this;
	},
	
	custom: function(velx, vely){
		this.velocity.x += velx;
		this.velocity.y += vely;
	},
	
	end: function(){
		this.options.onComplete.pass(this.el, this).delay(10);
		this.clearTimer();
	},
	
	clearTimer: function(){
		this.timer = $clear(this.timer);
	}
});
