/**
*	Comments User Interface
*
*	@author     Chris Constandinou <chris@constantology.com>
*
*/		
		Event.observe( window, 'load', function()
		{
			new CLO.CommentsUI(
				 {
					id : 'comments', 
/*					effect : {
						type : 'lightbox', 
						options : {
							center : false, 
							partial : true, 
							extraClassNames : 'comment-lightbox'
						}
					}, */
					trigger : null
				}, 
				{
					action : 'add', 
					id : 'post-comment', 
					effect : { type : 'blind' }, 
/*					effect : { 
						type : 'lightbox', 
						options : { extraClassNames : 'post-lightbox' } 
					}, */
					trigger : 'com-post'
				}, 
				{
					effect : {
						type : 'lightbox', 
						options : { extraClassNames : 'preview-lightbox' }
					}, 
					trigger : 'com-preview', 
					url : '/comment.html'
				}
			);
		}, false );
		
		CLO.CommentsUI = Class.create();
		CLO.CommentsUI.addMethods({
/*
*	PUBLIC METHODS
*/
			initialize : function( oCommentView, oPostForm, oPreview )
			{
				this.args = arguments;
				this.COMMENTS = $( oCommentView.id );
				this.POST_COMMENT = $( oPostForm.id );
				
				if ( this.COMMENTS ) 
				{
					if ( oCommentView.effect )
					{
						if ( oCommentView.trigger )
						{
							this.TRIGGER = $( oCommentView.trigger );
							Event.observe( this.TRIGGER, 'click', this.commentShow.bind( this ), false );
						}
						this._createEffect.call( this, this.COMMENTS, oCommentView.effect, 'comment' );
					}
					else
					{
						if ( oCommentView.trigger )
						{
							this.TRIGGER = $( oCommentView.trigger );
							Event.observe( this.TRIGGER, 'click', function( evt ) { new Effect.ScrollTo( this.COMMENTS ); Event.stop( evt ); }.bind( this ), false );
						}
					}
				}
				
				if ( this.POST_COMMENT && oPostForm.effect )
				{
					this.POST_TRIGGER = oPostForm.trigger;
					Event.observe( this.POST_TRIGGER, 'click', this.handlePost.bind( this ), false );
					
					if ( this._createPostDom.call( this, oPostForm.trigger ) )
						this._createEffect.call( this, this.postLoader, { type : 'lightbox', options : { extraClassNames : 'loader-lightbox', noScroll : true } }, 'loader' );
					
//	if there is a preview we want to set it to the original post action which should be to the preview screen
					if ( oPreview )
					{
						this._createPreviewButton.call( this, oPostForm.trigger, oPreview.trigger );
						oPreview.url = this.POST_COMMENT.getAttribute( 'action' );
					}
//	swap post action to the real one now
					this.POST_COMMENT.setAttribute( 'action', this.POST_COMMENT.getAttribute( 'action' ).replace( /^(.*\/).*$/, "$1" + oPostForm.action ) );
					
					//this.COMMENTS.insertBefore( cssQuery( 'div.com-actions', this.COMMENTS )[0].cloneNode( true ), this.POST_COMMENT );
					
					cssQuery( 'a[href*="post-comment"]', this.COMMENTS ).each( function( a ) {
						Event.observe( a, 'click', this.postShow.bind( this ), false );
					}.bind( this ) );
					
					this._createEffect.call( this, this.POST_COMMENT, oPostForm.effect, 'post' );
				}
				
				if ( this.POST_COMMENT && oPreview && oPreview.url )
				{
					this.TRIGGER_PREVIEW = $( oPreview.trigger );
					Event.observe( this.TRIGGER_PREVIEW, 'click', this.previewComment.bind( this, oPreview.url ), false );
					
					if ( oPreview.effect && this._createPreviewDom.call( this, oPreview.trigger ) )
						this._createEffect.call( this, this.previewTarget, oPreview.effect, 'preview' );
				}
			}, 
			
			commentHide : function( evt )
			{
				if ( this.commentLightbox )
					this.commentLightbox.hide();
				Event.stop( evt );
			}, 
			
			commentShow : function( evt )
			{
				if ( this.commentLightbox )
					this.commentLightbox.show();
				else if ( this.commentEffectShow )
					this.commentEffectShow( this.COMMENTS );
					
				Event.stop( evt );
			}, 
			
			handlePost : function( evt )
			{
				this.previewHide.call( this );
				console.log(this.validate.call( this ));
				if ( this.validate.call( this ) )
				{
					new Ajax.Request( 
						this.POST_COMMENT.getAttribute( 'action' ), 
//						'/comments.inc', 
						{
							method : 'post', 
							postBody : Form.serialize( this.POST_COMMENT ), 
							onFailure : this._handleFailure.bind( this, 'loaderHide' ), 
							on404 : this._handleFailure.bind( this, 'loaderHide' ), 
							onLoaded : this._toggleIndicator.bind( this, 'loaded' ), 
							onLoading : this._toggleIndicator.bind( this, 'loading', 'loaderShow' ), 
							onSuccess : this._handlePost.bind( this ) 
						}
					);
				}
				
				Event.stop( evt );
			}, 
			
			loaderHide : function( evt )
			{
				if ( this.loaderLightbox )
					this.loaderLightbox.hide();
				
				if ( evt )
					Event.stop( evt );
			}, 
			
			loaderShow : function( evt )
			{
				if ( this.loaderLightbox )
					this.loaderLightbox.show();
				
				if ( evt )
					Event.stop( evt );
			}, 
			
			postHide : function( evt )
			{
				if ( this.postLightbox )
					this.postLightbox.hide();
					
				Event.stop( evt );
			}, 
			
			postShow : function( evt )
			{
				if ( !Element.visible( this.POST_COMMENT ) && this.postEffectShow )
					new this.postEffectShow( this.POST_COMMENT );
				
//	only scroll to the point if we are not using a lightbox effect
				if ( this.postEffectScrollTo && !this.commentLightbox )
					new this.postEffectScrollTo( this.POST_COMMENT );
				
				if ( this.postLightbox )
					this.postLightbox.show();
					
				Event.stop( evt );
			}, 
			
			previewComment : function( url, evt )
			{
				if ( this.validate.call( this ) )
				{
					new Ajax.Request( 
						url, 
						{
							method : 'post', 
							postBody : Form.serialize( this.POST_COMMENT ), 
							onFailure : this._handleFailure.bind( this, null ), 
							on404 : this._handleFailure.bind( this, null ), 
							onLoading : this._toggleIndicator.bind( this, 'loading', 'previewShow' ), 
							onLoaded : this._toggleIndicator.bind( this, 'loaded', false ), 
							onSuccess : this._handlePreview.bind( this ) 
						}
					);
				}
				
				Event.stop( evt );
			}, 
			
			previewHide : function( evt )
			{
				if ( this.previewLightbox )
				{
					this.previewLightbox.hide();
					if ( !this.postLightBox )
					{
//	IE is throwing an obscure JS error so I'm using a "non-effect" scroll function for it
						if(  !/MSIE/i.test( navigator.userAgent ) )
							new Effect.ScrollTo( this.POST_COMMENT );
						else 
							Element.scrollTo( this.POST_COMMENT );
					}
				}
					
				if ( evt )
					Event.stop( evt );
			}, 
			
			previewShow : function( evt )
			{
				if ( this.previewLightbox )
					this.previewLightbox.show();
					
				if ( evt )
					Event.stop( evt );
			}, 
			
			validate : function()
			{
				var valid = [];
				valid.push( this._validate.call( this, 'com-name', 'Please enter your name.' ) );
				valid.push( this._validate.call( this, 'com-email', 'Please enter a valid email address.', /^[^@]+@[^@.]+\.[^@]*\w\w$/ ) );
				valid.push( this._validate.call( this, 'comment', 'Please enter your comments.' ) );
				valid.push( this._validate.call( this, 'captcha', 'Please enter the correct captcha.' ) );
					
				return valid.all();
			}, 
/*
*	PRIVATE METHODS
*/
			
			_buildErrorMessage : function( field, msg )
			{
				if ( cssQuery( 'span.error-msg', $( field ).parentNode ).length < 1 )
					$( field ).parentNode.appendChild( 
						Builder.node( 'span', { 'class' : 'error-msg' }, msg )
					);
			}, 
			
			_createCloseLighBoxButtons : function( obj, prefix )
			{
				var button = Builder.node( 
					'a', 
					{  
						'class' : 'com-close', 
						href  : '#close'
					}, 
					[ Builder.node( 'span', 'Close window' ) ]
				);
				
				var button2 = button.cloneNode( true );
				Element.addClassName( button2, 'bottom-align' );
				
				Element.observe( button, 'click', this[prefix + 'Hide'].bind( this ), false );
				
				Element.observe( button2, 'click', this[prefix + 'Hide'].bind( this ), false );
				
				obj.insertBefore( button, obj.firstChild );
				obj.appendChild( button2 );
			}, 
			
			_createEffect : function( obj, effect, prefix )
			{
				Element.toggle( obj );
				switch ( effect.type )
				{
					case 'blind' : 
						Element.addClassName( obj, 'blind-effect' );
						this[prefix + 'EffectShow'] = Effect.BlindDown;
						this[prefix + 'EffectScrollTo'] = Effect.ScrollTo;
						this[prefix + 'EffectHide'] = Effect.BlindUp;
						break;
					case 'lightbox' : 
						Element.addClassName( obj, 'lightbox-effect' );
						this[prefix + 'Lightbox'] = new CLO.LightBox( obj, ( effect.options || {} ) );
						if ( !/preview|loader/i.test( prefix ) )
							this._createCloseLighBoxButtons.call( this, obj, prefix );
						break;
				}
			}, 
			
			_createPreviewButton : function( insertBeforeObj, id )
			{
				var obj = $( insertBeforeObj );
				var previewButton = Builder.node(
					'a', 
					{ 'class' : 'button', href : '#', id : 'com-preview' }, 
					[Builder.node( 'span', 'Preview' )]
				);
				
				var actions = cssQuery( 'p.action', this.POST_COMENT )[0];
				actions.insertBefore( previewButton, actions.firstChild );
			}, 
			
			_createPreviewDom : function( id )
			{
				try { 
					var previewCloseButton = Builder.node( 
							'a', 
							{ 'class' : 'com-close', href : '#' }, 
							[Builder.node( 'span', 'Close preview pane' )]
						);
					var previewPostButton = Builder.node( 
							'a', 
							{ 'class' : 'button', href : '#' }, 
							[
								Builder.node( 'span', 'Post Comment' )
							]
						);
						
					document.body.appendChild( 
						Builder.node( 
							'div', 
							{ 'id' : id + '-dom' }, 
							[
								Builder.node( 
									'div', 
									{ 'class' : id + '-taskbar' }, 
									[
										Builder.node( 
											'h3', 
											'This is only a preview'
										), 
										previewCloseButton
									]
								), 
								Builder.node(  'div', { 'class' : id + '-target' } ), 
								Builder.node( 
									'div', 
									{ 'class' : id + '-taskbar' }, 
									[
										Builder.node( 
											'h3', 
											'This is only a preview'
										), 
										previewPostButton
									]
								) 
							]
						)
					);
					Event.observe( previewCloseButton, 'click', this.previewHide.bind( this ), false );
					Event.observe( previewPostButton, 'click', this.handlePost.bind( this ), false );
					this.previewTarget = $( id + '-dom' );
				}
				catch ( e ) { return false; }
				
				return true;
			}, 
			
			_createPostDom : function( id )
			{
				try { 
					document.body.appendChild( 
						Builder.node( 
							'div', 
							{ 'id' : id + '-dom' }, 
							[
								Builder.node( 
									'h3', 
									'Please wait while we post your comment.'
								) 
							]
						)
					);
					this.postLoader = $( id + '-dom' );
				}
				catch ( e ) { return false; }
				
				return true;
			}, 
			
			_handleFailure : function( func, response )
			{
				if ( func ) this[func].call( this );

				console.log( "request failed. " + response.statusText );
				console.log( response );
				document.getElementById('captcha_error').innerHTML = 'Please enter the captcha.';
			}, 
			
			_handlePreview : function( response )
			{
				if ( Element.hasClassName( this.previewTarget, 'loading' ) )
					Element.removeClassName( this.previewTarget, 'loading' );
				cssQuery( 'div[class*=target]', this.previewTarget )[0].innerHTML = response.responseText;
			}, 
			
			_handlePost : function( response )
			{
				var comments = document.createElement( 'div' );
				comments.innerHTML = response.responseText;

				try { 
					this.COMMENTS.innerHTML = comments.getElementsByTagName( 'div' )[0].innerHTML;
					this._handleResetPage.call( this );
				} catch ( e ) { }
				
				this.loaderHide.call( this );
			}, 
			
			_handleResetPage : function()
			{
				cssQuery( 'div[id$=-dom]' ).each( function( element )
				{
					document.body.removeChild( element );
				}.bind( this ) );
				
				cssQuery( 'div[class~=lightbox]' ).each( function( element )
				{
					document.body.removeChild( element );
				}.bind( this ) );
				
				this.initialize.call( this, this.args[0], this.args[1], this.args[2] );
			}, 
			
			_toggleIndicator : function( status, func, response )
			{
				if ( /loading/i.test( status ) )
					Element.addClassName( this.previewTarget, 'loading' );
				else
					Element.removeClassName( this.previewTarget, 'loading' );
				
				if ( func ) 
					this[func].call( this );
			}, 
			
			_validate : function( field, msg )
			{
				var valid = true;
				
				if ( $F( field ) == '' || ( arguments[2] && !arguments[2].test( $F( field ) ) ) )
				{
					Element.addClassName( $( field ).parentNode, 'error' );
					
					this._buildErrorMessage.call( this, field, msg )
					
					valid = false;
				}
				else
				{
					Element.removeClassName( $( field ).parentNode, 'error' );
					var errorMsg = cssQuery( 'span.error-msg', $( field ).parentNode )[0];
					if ( errorMsg )
						Element.remove( errorMsg );
				}
				
				return valid;
			}
		});
			
/**
*	LightBox UI effect
*
*	@author     Chris Constandinou <chris@constantology.com>
*
**/

		CLO.LightBox = Class.create();
		CLO.LightBox.addMethods({
			initialize : function( obj, options )
			{
				this.options = $H( {
					center : true, 
					noScroll : false, 
					partial : false
				} ).merge( options || {} );
				
				this.LIGHTBOX = Builder.node( 
					'div', 
					{ 
						'class' : 'lightbox', 
						'style' : 'display : none ;'
					},
					[
						Builder.node( 
							'div', 
							{ 'class' : 'lightbox-copy ' }
						)
					]
				);
				document.body.appendChild( this.LIGHTBOX );
				
				if ( this.options.get("extraClassNames") )
					Element.addClassName( this.LIGHTBOX, this.options.get("extraClassNames") );
				
				this.LIGHTBOX_COPY = $( obj );
		//	this is for IE mainly but we will use this also for a common centre effect
				document.body.appendChild( this.LIGHTBOX_COPY );
				
				this.LIGHTBOX.setAttribute( 'visible', 'false' );
				
				this.LIGHTBOX.style.height = this.getDimension()['docHeight'] + 'px';
				this.LIGHTBOX.style.width = this.getDimension()['docWidth'] + 'px';
				
		//	resize is crashing IE, so...
				if ( !window.attachEvent )
					Event.observe( window, 'resize', this.setDimensions.bind( this ), false );
				
				if ( this.options.get("partial") && navigator.appVersion.match( /MSIE/i ) )
					document.body.appendChild( Builder.node( 'div', { id : 'ie-fix' } ) );
			},
			
			centerCopy : function()
			{
				if ( navigator.appVersion.match( /MSIE/i ) || document.defaultView.getComputedStyle( this.LIGHTBOX_COPY, null ) )
					this.LIGHTBOX_COPY.style.left = ( this.getDimension()['docWidth'] - parseInt( Element.getStyle( this.LIGHTBOX_COPY, 'width' ) ) ) / 2 + 'px';
				else
					this.LIGHTBOX_COPY.style.left = '15%';
			}, 
			
			getDimension : function()
			{
				return { 
					docHeight : document.body.clientHeight + 50, 
					docWidth : document.body.clientWidth, 
					winHeight : ( window.innerHeight || document.documentElement.offsetHeight ) - 50, 
					winWidth : ( window.innerWidth || document.documentElement.offsetWidth )
				};
			}, 
			
			hide : function( obj )
			{
				Effect.Fade( 
					this.LIGHTBOX_COPY, 
					{
						duration : 0.5, 
						afterFinish: function()
						{
							if ( this.options.get("extraClassNames") )
								this.togglePageContainer.call( this, this.options.get("extraClassNames"), 'remove' );
								
							Effect.Fade( this.LIGHTBOX,{duration : 0.5});
						}.bind(this) 
					} 
				);
				
				if ( this.options.get("partial") && navigator.appVersion.match( /MSIE/i ) )
				{
					this.toggleIEPotisionFixed.call( this, false );
					this.toggleSelectLists.call( this, 'visible' );
				}
				
				this.LIGHTBOX.setAttribute( 'visible', 'false' );
				
				if ( obj )
					new Effect.ScrollTo( obj );
			}, 
			
			setDimensions : function()
			{
//			console.log( document.documentElement.offsetHeight );
				if ( this.options.get("partial") )
				{
					this.LIGHTBOX_COPY.style.height = this.getDimension()['winHeight'] + 'px';
					
					this.LIGHTBOX.style.height = this.getDimension()['docHeight'] + 'px';
				}
				else
				{
					this.LIGHTBOX.style.height = this.getDimension()['docHeight'] + 'px';
					this.LIGHTBOX.style.width = this.getDimension()['docWidth'] + 'px';
				}
				
				if ( this.options.get("center") )
					this.centerCopy.call( this );
			}, 

			show : function()
			{
				if ( this.options.get("partial") )
				{
					if ( navigator.appVersion.match( /MSIE/i ) )
					{
						this.toggleSelectLists.call( this, 'hidden' );
						this.toggleIEPotisionFixed.call( this, true );
					}
					
					if ( this.options.get("extraClassNames") )
						this.togglePageContainer.call( this, this.options.get("extraClassNames"), 'add' );
				}
				this.setDimensions.call( this );
					
				Effect.Appear( 
					this.LIGHTBOX, 
					{ 
						duration : 0.5, 
						to: 0.8, 
						afterFinish: function()
						{
							if ( this.options.get("noScroll") )
								this.LIGHTBOX_COPY.style.top = ( ( window.pageYOffset
															                || document.documentElement.scrollTop
															                || document.body.scrollTop
															                || 0 ) + 50 ) + 'px'; 
																			
							Effect.Appear( this.LIGHTBOX_COPY, { duration : 0.5 } );
						}.bind(this) 
					} 
				);
				
				this.LIGHTBOX.setAttribute( 'visible', 'true' );
				
				if ( !this.options.get("noScroll") )
					new Effect.ScrollTo( document.body );
//				window.scroll( 0, 0 );
			}, 
			
			toggleIEPotisionFixed : function( showLightBox )
			{
				if ( showLightBox )
					$( 'ie-fix' ).appendChild( document.getElementsByTagName( 'div' )[0] );
				else
					document.body.insertBefore( $( 'ie-fix' ).getElementsByTagName( 'div' )[0], document.body.firstChild );
			}, 
			
			togglePageContainer : function( className, type )
			{
				Element[type + 'ClassName']( document.documentElement, className );
			}, 
			
			toggleSelectLists : function( visibility )
			{
				cssQuery( 'select' ).each( function( list )
				{
					list.style.visbility = visibility;
				} );
			}
		});
