// clickStart namespace
var ClickStart = {};

// audio constructor
ClickStart.Audio = Class.create( {
	initialize : function() {
		document.observe( 'click', this.clickAndKeypress.bind( this ) );
		document.observe( 'audio:play', this.play.bind( this ) );
		document.observe( 'audio:stop', this.stop.bind( this ) );
	},
	clickAndKeypress : function( event ) {
		var target = event.findElement( 'a' );
		if ( target ) {
			switch ( target.className ) {
				case 'play' :
					event.stop();
					document.fire( 'audio:play', { target : target } );
					break;
				case 'stop' :
					event.stop();
					document.fire( 'audio:stop', { target : target } );
					break;
				default :
					return;
			};
		};
	},
	play : function( event ) {
		Sound.enable();
		Sound.play( event.memo.target.href, { replace : true } );
	},
	stop : function( event ) {
		Sound.disable();
	}
} );

// abstract constructor
ClickStart.Abstract = Class.create( {
	initialize : function( element ) {
		this.element = $( element );
		if ( this.element ) {
			this.addObservers( {
				'click' : this.clickAndKeypress.bind( this ),
				'keypress' : this.clickAndKeypress.bind( this )
			} );
		};
	},
	addObservers : function( observers ) {
		$H( observers ).each( function( observer ) {
			this.element.observe( observer.key, observer.value );
		}.bind( this ) );
	}
} );

// form constructor
ClickStart.Form = Class.create( ClickStart.Abstract, {
	initialize : function( $super, element, options ) {
		$super( element );
		this.element = $( element );
		this.options = Object.clone( options || { } );
		this.isValid = null;
		this.firstError = null;
		this.controls = [];
		this.options.controls.each( function( control ) {
			var control = new ClickStart.Control( control.id, control.options );
			var matchControlId = control.options.matchControlId;
			if ( matchControlId ) {
				control.matchControl = this.controls.find( function( control ) {
					if ( control.id == matchControlId ) {
						return control;
					};
				}.bind( this ) );
				control.matchControl.element.observe( 'control:validate', control.validate.bind( control ) );
			};	
			this.controls.push( control );
		}.bind( this ) );
		this.addObservers( {
			/*'submit' : this.submit.bind( this ),*/
			'form:validate' : this.validate.bind( this ),
			'form:respond' : this.respond.bind( this )
		} );
	},
	clickAndKeypress : function( event ) {
		/*var target = event.findElement( 'a' ) || event.findElement( 'input' );
		if ( !target ) {
			return;
		};
		if ( target.hasClassName( 'select' ) ) {
			event.stop();
			var href = target.href;
			$( href.substring( href.indexOf( '#' ) + 1, href.length ) ).activate();
		}
		else if ( target.hasClassName( 'next' ) || target.hasClassName( 'save' ) || target.hasClassName( 'login' ) || target.hasClassName( 'send' ) ) {
			this.element.fire( 'form:validate' );
		};*/
	},
	submit : function( event ) {
		event.stop();
	},
	validate : function( event ) {
		var messages = [];
		var controls = [];
		this.isValid = true;
		this.firstError = null;
		this.controls.each( function( control ) {
			control.element.fire( 'control:validate', { submit : true } );
			if ( control.isValid ) {
				
			}
			else {
				messages.push( control.message );
				controls.push( control );
				control.element.fire( 'control:respond', { response : 'error' } );
				if ( !this.firstError ) {
					this.firstError = control;
				};
				this.isValid = false;
			};
		}.bind( this ) );
		if ( this.isValid ) {
			this.element.submit();
		}
		else {
			this.element.fire( 'form:respond', { messages : messages, controls : controls } );
			this.firstError.element.focus();
		};
	},
	respond : function( event ) {
		var messages = '';
		var margin = 30;
		this.errors = this.element.select( 'div.errors ul' )[ 0 ];
		
		
		if ( this.errors ) {
			this.errors.up( 0 ).remove();
			this.errors.setStyle( { marginBottom : '30px' } );
		};
		
		if ( event.memo.messages.length > 2 ) {
			margin += ( ( event.memo.messages.length - 2 ) * 28 );
		};
		
		
		this.element.select( 'fieldset' )[ 0 ].insert( { before : '<div class="errors"><h2 class="access">errors</h2><ul></ul></div>' } );
		this.errors = this.element.select( 'div.errors ul' )[ 0 ];
		event.memo.messages.each( function( message, index ) {
			messages += '<li><a class="select" href="#' + event.memo.controls[ index ].element.id + '">' + message + '</a></li>';
		} );
		this.errors.update( messages );
		this.errors.up( 0 ).setStyle( { marginBottom : margin + 'px' } );
	}
} );

// control constructor
ClickStart.Control = Class.create( {
	initialize : function( element, options ) {
		this.element = $( element );
		this.options = Object.clone( options || { } );
		this.isValid = null;
		this.matchControl = null;
		this.element.observe( 'keyup', this.keyup.bind( this ) );
		this.element.observe( 'keydown', this.keydown.bind( this ) );
		this.element.observe( 'mouseup', this.mouseup.bind( this ) );
		this.element.observe( 'control:validate', this.validate.bind( this ) );
		this.element.observe( 'control:respond', this.respond.bind( this ) );
		this.tooltip = new ClickStart.Tooltip( this.element );
		if ( this.element.tagName.toUpperCase() === 'FIELDSET' ) {
			this.labelText = this.element.select( 'legend span' )[ 0 ].innerHTML;
		}
		else {
			this.labelText = this.element.up( 0 ).select( 'label' ) [ 0 ].innerHTML;
		};
		this.message = '';
		if ( this.element.readAttribute( 'type' ) == 'file' ) {
			/*
			if ( !Prototype.Browser.IE ) {
				this.element.setStyle( { opacity : '0' } );
				this.element.insert( { after : '<span class="file">&nbsp;</span>' } );
				this.file = this.element.up( 0 ).select( 'span.file' )[ 0 ];
				this.element.observe( 'change', function() {
					var value = this.element.getValue();
					if ( value.length > 1 ) {
						this.file.innerHTML = value;
					};
				}.bind( this ) );
				this.element.observe( 'click', function() {
					var value = this.element.getValue();
					if ( value.length > 1 ) {
						this.file.innerHTML = value;
					};
				}.bind( this ) );
				this.element.observe( 'keypress', function() {
					var value = this.element.getValue();
					if ( value.length > 1 ) {
						this.file.innerHTML = value;
					};
				}.bind( this ) );
				this.element.observe( 'change', function() {
					this.element.fire( 'control:validate' );
				}.bind( this ) );
			}
			else {
				this.element.setStyle( { position : 'static', width : '300px' } );
			};
			*/
		}
		else if ( this.element.tagName.toUpperCase() == 'SELECT' ) {
			
		};
	},
	keyup : function( event ) {
		if ( event.keyCode == Event.KEY_TAB ) {
			if ( !this.isValid ) {
				this.element.fire( 'control:respond', { response : 'error' } );
			};
		}
		else {
			this.element.fire( 'control:validate' );
		};
	},
	keydown : function( event ) {
		if ( event.keyCode == Event.KEY_TAB ) {
			
		};
	},
	mouseup : function( event ) {
		this.element.fire( 'control:validate' );
	},
	validate : function( event ) {
		var radios;
		var checked;
		var value;
		var tagName = this.element.tagName.toUpperCase();
		var required = this.options.required;
		var minLength = this.options.minLength;
		var methods = this.options.methods;
		var matchControl = this.matchControl;
		
		if ( event.memo.submit == true || this.attempted == true ) {
		
			this.message = '';
			if ( matchControl ) {
				var matchValue = matchControl.element.getValue();
			};
			this.isValid = true;
			if ( tagName === 'FIELDSET' ) {
				radios = this.element.select( 'input[type="radio"]' );
				if ( radios ) {
					radios.each( function( radio ) {
						if ( radio.checked ) {
							checked = true;
						};
					} );
					if ( !checked ) {
						this.isValid = false;
						this.message = ' is required'
					};
				};
			}
			else if ( tagName === 'INPUT' || tagName === 'TEXTAREA' ) {
				value = this.element.getValue();
				if ( required ) {
					if ( value.length < 1 ) {
						this.isValid = false;
						this.message = ' is required'
					}
					else if ( minLength && value.length < minLength ) {
						this.isValid = false;
						this.message = ' is required to be ' + minLength + ' characters or more';
					};
				};
				if ( methods && methods.length > 0 ) {
					methods.each( function( method ){
						var response = method( value );
						if ( response != true ) {
							this.isValid = false;
							this.message = response;
						};
					}.bind( this )  );
				};
				if ( matchControl && this.isValid ) {
					if ( value != matchValue ) {
						this.isValid = false;
						this.message = matchControl.labelText + ' is required to be the same as ' + this.labelText;
					};
				};
			}
			else if ( tagName === 'SELECT' ) {
				if ( required ) {
					if ( this.element.selectedIndex == 0 ) {
						this.isValid = false;
						this.message = ' is required'
					};
				};
			};
			if ( this.message ) {
				this.message = this.labelText + this.message;
			};
			if ( this.isValid ) {
				this.element.fire( 'control:respond', { response : 'ok' } );
			}
			else {
				this.element.fire( 'control:respond', { response : 'warning' } );
			};
			this.attempted = true;
		};
	},
	respond : function( event ) {
		var container;
		if ( this.element.tagName.toUpperCase() === "FIELDSET" ) {
			container = this.element;
		}
		else {
			container = this.element.up( 0 );
		};
		switch ( event.memo.response ) {
			case 'ok' :
				container.removeClassName( 'error' );
				container.addClassName( 'ok' );
				break;
			case 'warning' :
				container.removeClassName( 'ok' );
				container.addClassName( 'error' );
				break;
			case 'error' :
				
				break;
			default :
				
		};
	}
} );

// tooltip constructor
ClickStart.Tooltip = Class.create( ClickStart.Abstract, {
	initialize : function( $super, element ) {
		var element = $( element );
		if ( element.tagName.toUpperCase() == 'FIELDSET' ) {
			var label = element.select( 'legend span' )[ 0 ];
			var text = element.readAttribute( 'title' );
			element.writeAttribute( { 'title' : '' } );
			element.insert( { bottom : '<a href="#' + element.id + '-tooltip" class="tooltip" tabindex="-1">' + label.innerHTML + ' tip</a>' } );
		}
		else {
			var label = element.up( 0 ).select( 'label' )[ 0 ];
			var text = label.readAttribute( 'title' );
			label.writeAttribute( { 'title' : '' } );
			element.insert( { after : '<a href="#' + element.id + '-tooltip" class="tooltip" tabindex="-1">' + label.innerHTML + ' tip</a>' } );
		};
		if ( element.tagName.toUpperCase() == 'FIELDSET' ) {
			this.element = element.select( 'a.tooltip' )[ 0 ];
		}
		else {
			this.element = element.up( 0 ).select( 'a.tooltip' )[ 0 ];
		};
		$super( this.element );
		this.animating = false;
		this.element.insert( { after : '<span id="' + element.id + '-tooltip" class="tooltip"><em>' + text + '</em></span>' } );
		this.target = this.element.next( 0 );
                this.target.hide();
		this.addObservers( {
			'tooltip:open' : this.open.bind( this ),
			'tooltip:close' : this.close.bind( this )
		} );
		this.element.fire( 'tooltip:close' );
		document.observe( 'tooltip:close', this.close.bind( this ) );
		document.observe( 'click', this.close.bind( this ) );
		document.observe( 'keypress', this.close.bind( this ) );
	},
	clickAndKeypress : function( event ) {
		var target = event.findElement( 'a' );
		if ( target.hasClassName( 'open' ) ) {
			event.stop();
			this.element.fire( 'tooltip:open' );
		}
		else if ( target.hasClassName( 'close' ) ) {
			event.stop();
			this.element.fire( 'tooltip:close' );
		};
	},
	open : function( event ) {
		var afterFinish = function() {
			this.animating = false;
		}.bind( this );
		this.element.removeClassName( 'open' );
		this.element.addClassName( 'close' );
		this.animating = new Effect.Appear( this.target, { from : 0, to : 1.0, duration : 0.5, afterFinish : afterFinish } );
		document.fire( 'tooltip:close' );
	},
	close : function( event ) {
		if ( this.animating ) {
			return;
		};
		this.element.removeClassName( 'close' );
		this.element.addClassName( 'open' );
		new Effect.Fade( this.target, { from : 1.0, to : 0, duration : 0.5 } );
	}
} );

// validator metods
ClickStart.Validator = {
	validEmail : function( value ) {
		var regEx = /(\w+[\w|\.|-]*\w+)(@\w+[\w|\.|-]*\w+\.\w{2,4})/;
		if ( regEx.test( value ) == false ) {
			return ' is required to be a valid email address';
		}
		else {
			return true;
		};
	}
};

// youTube connector
ClickStart.YouTubeInterface = Class.create( {
	initialize : function() {
		this.folder = $( 'folder' );
		this.choices = $( 'choices' ).select( 'ul' )[ 0 ];
		this.folder.observe( 'change', this.changeChoices.bind( this ) );
	},
	changeChoices : function( event ) {
		var target = event.target;
		var onSuccess = function( transport ) {
			this.choices.update( transport.responseText );
		};
		var onFailure = function() {
			new Effect.Shake( this.folder, { duration : 1, distance : 5 } );
		};
		new Ajax.Request( 'partials/choose-video.htm?folder=' + event.target.getValue() + '&ajax=true', {
			method : 'get',
			onSuccess : onSuccess.bind( this ),
			onFailure : onFailure.bind( this )
		} );
	}
} );






