/*  Juice Library popover.juice.js, version 0.1.1.20080218
 *  Copyright (c) 2007, 2008 Stephen Whiteley (http://jui.ce.it)
 *
 *  See core.juice.js for full license.
 *
/*--------------------------------------------------------------------------*/

(function(){

	if ( typeof Juice == 'undefined' ) {
		throw new Error( 'popover.juice.js requires the core.juice.js component.' );
	}

	Juice.Popover = function( setup ) {

		var popover, container, shadow, header, content, inner, overlay, iframe, size = {}, myself = this;

		this.setup = function() {

			popover = {
				parent: Juice.Element.output( Juice.Prefs.container ),
				directory: Juice.Prefs.image + 'popover/',
				border: setup.border ||  1,
				padding: setup.padding || 10,
				reload: setup.reload ? true : false
			};

			overlay						= Juice.Element.create( 'DIV', null, 'overlay' );
			overlay.style.visibility	= 'hidden';
			overlay.style.position		= 'absolute';
			overlay.style.zIndex		= '900';
			overlay.style.width			= '100%';
			overlay.style.background	= setup.background || 'black';
			overlay.style.top = overlay.style.left = 0;

			container					= Juice.Element.create( 'DIV' );
			container.style.visibility	= 'hidden';
			container.style.position	= 'absolute';
			container.style.zIndex		= '910';
			container.style.padding		= '8px';
			container.style.top = container.style.left = 0;

			shadow						= Juice.Element.create( 'DIV' );
			shadow.style.zIndex			= '915';
			shadow.style.background		= setup.shadow || 'black';
			shadow.style.position		= 'absolute';
			shadow.style.top = shadow.style.left = 0;
			shadow.style.width = shadow.style.height = '100%';

			container.appendChild( shadow );

			inner						= Juice.Element.create( 'DIV' );
			inner.style.zIndex			= '920';
			inner.style.position		= 'relative';
			inner.style.background		= setup.color || 'white';
			inner.style.padding			= popover.padding + 'px';
			inner.style.border			= popover.border + 'px solid black';
			inner.style.backgroundPosition = 'center center';
			inner.style.backgroundRepeat = 'no-repeat';

			container.appendChild( inner );

			content						= Juice.Element.create( 'DIV' );
			content.style.zIndex		= '930';
			content.style.overflow		= 'auto';

			inner.appendChild( content );

			Juice.Element.opacity( overlay, setup.opacity || 50 );
			Juice.Element.opacity( shadow, setup.opacity / 1.5 || 30 );

			Juice.Event.add( overlay, 'click', myself.hide );
			Juice.Event.add( window, 'resize', myself.resize );
			Juice.Event.add( window, 'scroll', myself.position );

			myself.content( ( setup.type || 'frame' ), setup.action, ( setup.method || 'GET' ) );

		};

		this.content = function( type, action, method ) {

			myself.load();

			switch ( type ) {

				case 'ajax':

					if ( Juice.Ajax ) {

					var x = new Juice.Ajax();
						x.ready = function( res ) {
							myself.output( res );
							myself.parse( content );
						}
						x.request( action, method );

					} else {
						myself.error( 'ajax.juice.js componant is required to use ajax.' );
					}

				break;
				case 'image':

					var img = new Image();
						img.onload = function() {
							content.style.background = 'url(' + action + ' ) center center no-repeat';
							setup.width = img.width;
							setup.height = img.height;
							myself.output();
						};
						img.onerror = function() {
							myself.error( 'Failed to load image' );
						};
						img.src = action;

				break;
				case 'inline':

					var element;

					if ( element = Juice.$( action ) ) {
						myself.output( element.innerHTML );
						myself.parse( popover.content );
					} else {
						myself.error( 'Inline content element could not be found' );
					}

				break;
				case 'frame':

					iframe					= Juice.Element.create( 'IFRAME' );
					iframe.style.overflow	= 'auto';
					iframe.src				= action;
					iframe.style.border = iframe.frameBorder = 0;
					iframe.style.width = iframe.style.height = '100%';
					iframe.onload = iframe.onreadystatechange = myself.loaded;

					content.style.overflow = 'hidden';
					content.appendChild( iframe );

				break;
				default:

					myself.error( 'Invalid action type' );

			}

			myself.show();

		};

		this.load = function() {

			content.scrollTop = 0;
			inner.style.backgroundImage = 'url(' + popover.directory + 'loading.gif)';
			content.style.visibility = 'hidden';

		};

		this.loaded = function() {

			inner.style.backgroundImage = '';
			content.style.visibility = 'visible';

		};

		this.output = function( val ) {

			myself.size();
			myself.position();
			myself.loaded();

			if ( val ) { content.innerHTML = val; }

		};

		this.error = function( err ) {

			myself.hide();

			Juice.Debug( new Error( 'Juice.Popover: ' + err ) );

		};

		this.encode = function( name, value ) {

			return encodeURIComponent( name ) + '=' + encodeURIComponent( value );

		};

		this.overlay = function() {

			if ( overlay.parentNode ) {
				popover.parent.removeChild( overlay );
			}

			var page = Juice.Browser.inner();

			overlay.style.height = page.height + 'px';

			popover.parent.appendChild( overlay );

			Juice.Element.obstructions( overlay );

		};

		this.show = function() {

			popover.offset = popover.border + popover.padding;

			popover.parent.appendChild( container );

			myself.resize();

			overlay.style.visibility = container.style.visibility = 'visible';

		};

		this.resize = function() {

			myself.size();
			myself.overlay();
			myself.position();

		};

		this.size = function( type ) {

			var limits = Juice.Browser.dimensions(), width, height;			

			size.max = {
				width: limits.width - 100,
				height: limits.height - 100
			};

			switch ( type ) {
				case 'max':
					width = size.max.width;
					height = size.max.height;
				break;
				default:
					width = setup.width;
					height = setup.height;
			}

			if ( height ) {
				if ( typeof height == 'number' ) {
					height = height;
				} else if ( ( height.toString() ) && ( height.substring( height.length - 1 ) == '%' ) ) {
					height = ( limits.height / 100 ) * parseInt( height );
				}
			} else {
				height = ( limits.height / 100 ) * 30;
			}

			if ( height > size.max.height ) {
				height = size.max.height;
			}

			if ( width ) {
				if ( typeof width == 'number' ) {
					width = width;
				} else if ( ( width.toString() ) && ( width.substring( width.length - 1 ) == '%' ) ) {
					width = ( limits.width / 100 ) * parseInt( width );
				}
			} else {
				width = ( limits.width / 100 ) * 30;
			}

			if ( width > size.max.width ) {
				width = size.max.width;
			}

			size.height = height;
			size.width = width;

			if ( !Juice.Browser.detect().ie6 ) {
				shadow.style.width = ( size.width + ( ( popover.border + popover.padding ) * 2 ) + 18 ) + 'px';
				shadow.style.height = ( size.height + ( ( popover.border + popover.padding ) * 2 ) + 18 ) + 'px';
			}

			content.style.height = ( size.height + ( popover.border * 2 ) ) + 'px';
			content.style.width = ( size.width + ( popover.border * 2 ) ) + 'px';

		};

		this.position = function() {

			var b = Juice.Browser.dimensions();
			var s = Juice.Element.scroll();
			var p = { top: 0, left: 0 };
			var o = Juice.Browser.detect().ie ? 0 : 9;

			p.top = ( b.height / 2 ) - ( ( size.height / 2 ) ) - ( popover.padding * 2 ) + s.top;
			p.left = ( b.width / 2 ) - ( ( size.width / 2 ) ) - ( popover.padding * 2 ) + s.left - o;

			container.style.top = p.top + 'px';
			container.style.left = p.left + 'px';

		};

		this.setReload = function( reload ) {

			 popover.reload = ( reload === true ? true : false );

		};

		this.hide = function() {

			if ( Juice.Type.callback( setup.onclose ) ) {
				setup.onclose( this );
			}

			if ( popover.reload === true ) {
				window.location.reload( true );
			}

			Juice.Event.remove( overlay, 'click', myself.hide );
			Juice.Event.remove( window, 'resize', myself.resize );
			Juice.Event.remove( window, 'scroll', myself.position );
			
			popover.parent.removeChild( container );
			popover.parent.removeChild( overlay );			

		};

		this.form = function( form ) {

			var url = append = '';

			for ( var i = 0; i < form.elements.length; i++ ) {

				var element = form.elements[i];

				switch( element.nodeName ) {
					case 'BUTTON':
					case 'TEXTAREA':
						append = myself.encode( element.name, element.value );
					break;
					case 'INPUT':
						switch( element.type ) {
							case 'text':
							case 'hidden':
							case 'password':
							case 'submit':
								append = myself.encode( element.name, element.value );
							break;
							case 'checkbox':
							case 'radio':
								if ( element.checked ) append = myself.encode( element.name, element.value );
							break;
						}
					break;
					case 'SELECT':
						var option;
						for ( var j in element.options ){
							if ( option = element.options[j] ){
								if ( option.selected ){
									if ( append ) {	append += '&'; }
									append += myself.encode( element.name, option.value );
								}
							}
						}
					break;
				}

				if ( append ) { url += ( url ? '&' : '' ) + append; }

			}

			myself.content( 'ajax', form.getAttribute( 'action' ) + '?' + url, ( form.method || 'GET' ) );

		};

		this.maximise = function() {

			myself.size( 'max' );
			myself.position();

		};

		this.minimise = function() {

			myself.size( );
			myself.position();

		};

		this.parse = function( node, base ) {

			if ( !node || node.nodeType != 1 ) return false;
			if ( !base ) base = node;

			var attr;

			if ( node.nodeName == 'FORM' ) {
				node.onsubmit = function() {
					myself.form( node );
					return false;
				}
			}

			if ( attr = node.getAttribute( 'popover' ) ) {
				switch ( attr ) {
					case 'autoclose':
						myself.hide();
					break;
					case 'close':
						node.onclick = myself.hide;
					break;
					case 'max':
						node.onclick = myself.maximise;
					break;
					case 'min':
						node.onclick = myself.minimise;
					break;
					case 'reload':
						myself.setReload( true );
					break;
				}
			}

			if ( node.childNodes ) {
				for ( var i = 0; i < node.childNodes.length; i++ ) {
					myself.parse( node.childNodes[i], base );
				}
			}

		};

		this.setup();

	}

})();