/**
 * @author Nathan Kelly - http://www.nathan-kelly.com/
 *  my email address is my first name @nathan-kelly.com
 * @copyright 2009 Nathan Kelly, all rights reserved
 * @package nk-form-functions
 * @version 1.0.0
 * @url http://www.nathan-kelly.com/
 * @dependencies
 * 	prototype.js 1.6.0.3+ (http://www.prototypejs.org/)
 *	scriptaculous.js 1.8.2+ (http://script.aculo.us/)
 */

var nk_form_functions = Class.create({

	initialize: function() {

		// protect forms
		if ( $$('.protected-form') ) {

			this.protectForms(false);

		}

		// PowerDeleteButtons and PowerDeleteConfirm fields
		if ( $$('.uis-remove') || $$('.power-delete-confirm') ) {

			this.removalActions();

		}

		// invert selection buttons
		if ( $$('.uis-invert') ) {

			this.invertSelections();

		}

		// Select Boxes
		if ( $$('select') ) {

			$$('select').each( function (e) {

				if ( e.multiple !== true ) {

					var i = 0;

					e.hide();

					new nk_pretty_selects(e, i);

					i++;

				}

			});

		}

		// File Inputs
		if ( $$('input[type=file]') ) {

			//var ie = 0 //@cc_on + @_jscript_version
			//if (window.opera || (ie && ie < 5.5) || !document.getElementsByTagName) { return; }

			new nk_pretty_fileinputs();

		}

	},
	// Protect forms
	protectForms: function( dirty) {

		$$('.protected-form').each( function (f) {

			$(f).getElements().each( function (e) {

				e.observe('change', ( function (c) {

					dirty = true;

				}).bind(this));

			});

			$(f).observe('submit', ( function (i) {

				dirty = false;

			}).bind(this));

			// use old style event observer for IE and Safari
			window.onbeforeunload = function () {

				if ( dirty === true ) {

					return 'There are unsaved changes, a new draft will be stored\nif you leave now but your changes will not be published.';

				}

			};

			$('discard-button').onclick = function () {

				$('discard-confirm').value = 0;

				if ( dirty === true ) {

					return confirm('Are you sure you want to discard your changes?');

				}

			};

		});

	},
	// removal actions for power delete
	removalActions: function () {

		$$('.power-delete-confirm').each( function (e) {

			$(e).value = 0;

		});

		$$('.uis-remove').each( function( e) {

			$(e).onclick = function () {

				var objectClass = $(e).title.split(' ')[1];

				if ( $(e).className.match(/uis-draft-mode/) ) {

					return confirm('Are you sure you want to remove this ' + objectClass + '?');

				} else {

					return confirm('Are you sure you want to remove this ' + objectClass + '?\nThis action connot be undone!');

				}

			};

		});

	},
	// invert selections
	invertSelections: function () {

		$$('.uis-invert').each( function (e) {

			$(e).observe('click', ( function( i) {

				Event.stop(i);

				var invertItems = $(e).id;

				$(e).className.match(/selected/) ? $(e).removeClassName('selected') : $(e).addClassName('selected');

				$$('.' + invertItems).each( function (l) {

					$(e).className.match(/selected/) ? $(l).checked = true : $(l).checked = false;

				});

			}).bind(this));

		});

	}

});

/**
 * @author Nathan Kelly - http://www.nathan-kelly.com/
 *  my email address is my first name @nathan-kelly.com
 * @copyright 2009 Nathan Kelly, all rights reserved
 * @package nk-form-functions
 * @metods nk_pretty_selects
 * @version 1.0.0
 * @url http://www.nathan-kelly.com/
 * @dependencies
 * 	prototype.js 1.6.0.3+ (http://www.prototypejs.org/)
 *	scriptaculous.js 1.8.2+ (http://script.aculo.us/)
 */

var nk_pretty_selects = Class.create({

	maxItems: 15,
	
	borderWidth: 1,
	
	initialize: function (select, idx) {
		
		this.selectorOpts = select.childElements();

		this.oldClassName = select.className;
		
		$($(select).parentNode).appendChild(

			//@ prototype <= 1.6.0.3 has issues with IE 8 when adding className. Use Builder instead for now
			//@ REF: https://prototype.lighthouseapp.com/projects/8886/tickets/529-element-constructor-doesnt-add-classname-in-ie8
			//new Element( 'ul', { id: select.id + '-select-replacement', className: 'ui-select-replacement' })
			Builder.node( 'ul', { id: select.name + '-select-replacement', className: ( this.oldClassName != '' ? this.oldClassName + ' ' : '' ) + 'ui-select-replacement' })
			
		);

		this.selector = $(select.name + '-select-replacement');

		this.selectorName = select.name + '-' + idx;

		this.sel = $(select).down('option[selected=selected]') ? $(select).down('option[selected=selected]', 0) : $(select).down('option', 0);

		$(this.selector).appendChild(
			Builder.node( 'li', { id: 'ui-opt-current-' + this.selectorName, className: 'ui-opt-selected-current' }, [
				Builder.node('button', { type: 'button' }, [
					Builder._text( 'select' )
				]),
				Builder.node( 'span', { id: 'ui-opt-current-' + this.selectorName + '-text', className: 'ui-selected-text' }, [
					Builder._text( this.sel.text )
				]),				
				Builder.node('ul', { id: 'ui-option-list-' + this.selectorName, className: 'ui-option-list' })
			])
		);
		
		this.current = $('ui-opt-current-' + this.selectorName);

		$(select).childElements().each( function (o) {

			o.id = 'ui-original-' + o.value + '-' + select.name + '-' + idx;

			var sel = o.selected === true ? ' ui-opt-selected' : '';

			$('ui-option-list-' + select.name + '-' + idx).appendChild(

				//@ prototype <= 1.6.0.3 has issues with IE 8 when adding className. Use Builder instead for now
				//@ REF: https://prototype.lighthouseapp.com/projects/8886/tickets/529-element-constructor-doesnt-add-classname-in-ie8
				//new Element( 'li', { id: 'ui-option-' + o.value + '-' + select.name + '-' + idx, className: 'ui-option-replacement' + sel }).update(o.text)
				Builder.node( 'li', { id: 'ui-option-' + o.value + '-' + select.name + '-' + idx, className: 'ui-option-replacement' + sel }, [
					Builder._text( o.text )
				])

			);

		});

		this.opts = this.selector.select('.ui-option-replacement');
		
		this.items = this.opts.length;
		
		this.list = $('ui-option-list-' + this.selectorName);

		this.listDims = this.list.getDimensions();
		
		this.itemDims = this.list.down('li', 0).getDimensions();		
		
		if ( this.items < this.maxItems ) {
			
			this.list.setStyle({
				width: (this.itemDims.width + this.borderWidth) + 'px',
				height: this.listDims + 'px',
				position: 'absolute',
				top: 'auto',
				left: 'auto'
			});
			
		} else {
			
			this.list.setStyle({
				width: (this.itemDims.width + this.borderWidth) + 'px',
				height: (this.maxItems * this.itemDims.height) + 'px',
				overflow: 'auto',
				position: 'absolute',
				top: 'auto',
				left: 'auto'
			});
			
		}
		
		this._hide();

		this.selected = this.selector.down('.ui-opt-selected', 0);
		
		this.events = {
			_ovr: this._ovr.bind(this),
			_out: this._out.bind(this),
			_clk: this._clk.bind(this)
		};

		this.opts.invoke( 'observe', 'mouseover', this.events._ovr );
		this.opts.invoke( 'observe', 'mouseout', this.events._out );
		//this.opts.invoke( 'observe', 'click', this.events._clk );
		document.observe( 'click', this.events._clk );

	},

	_ovr: function (event) {

		Event.stop(event);

		var elm = Event.findElement(event, 'li');

		this.opts.invoke('removeClassName', 'ui-opt-selected' );

		elm.addClassName('ui-hover');

	},

	_out: function (event) {

		Event.stop(event);

		var elm = Event.findElement(event, 'li');

		this.selected.addClassName('ui-opt-selected');

		elm.removeClassName('ui-hover');

	},

	_clk: function (event) {

		if ( !Event.element(event).descendantOf(this.selector) ) {

			// don't stop the bubbling or we will break other click events

			this._hide();

		} else {

			Event.stop(event);

			var elm = Event.findElement(event, 'li');

			if ( !elm.className.match(/ui-opt-selected-current/) ) {

				var parts = elm.id .split('-');

				var value = parts[2] + '-' + parts[3] + '-' + parts[4];

				this.opts.invoke('removeClassName', 'ui-opt-selected' );

				this._hide();

				elm.addClassName('ui-opt-selected');

				this.selectorOpts.each( function (e) {

						e.writeAttribute({ selected: false });

				});

				$('ui-original-' + value).writeAttribute({ selected: true });
				
				this.selected = this.selector.down('.ui-opt-selected', 0);

				$('ui-opt-current-' + this.selectorName + '-text').update( this.selected.innerHTML );

			} else {

				if ( this.closed === false ) {

					this._hide();					

				} else {

					this._show();					

				}

			}

		}

	},
	
	_hide: function () {
		
		this.list.hide();
					
		this.list.up('li').removeClassName( 'ui-select-open' );

		this.closed = true;
					
	},
	
	_show: function () {
		
		this.list.show();
					
		this.list.up('li').addClassName( 'ui-select-open' );

		this.closed = false;
					
	}

});

/**
 * @author Nathan Kelly - http://www.nathan-kelly.com/
 *  my email address is my first name @nathan-kelly.com
 * @copyright 2009 Nathan Kelly, all rights reserved
 * @package nk-form-functions
 * @metods nk_pretty_fileinputs
 * @version 1.0.0
 * @url http://www.nathan-kelly.com/
 * @dependencies
 * 	prototype.js 1.6.0.3+ (http://www.prototypejs.org/)
 *	scriptaculous.js 1.8.2+ (http://script.aculo.us/)
 */

var nk_pretty_fileinputs = Class.create({

	initialize: function () {

		$$('input[type=file]').each( function (e) {

			$(e).addClassName('ui-file-input-repaced');

			// we can't hide the input in the normal way because it will be unclickable
			$(e).setStyle( { opacity: 0 });

			$($(e).parentNode).appendChild(

				Builder.node( 'div', { className: 'ui-fake-file' }, [

						Builder.node( 'input', { className: 'ui-fake-path', type: 'text', value: $(e).value }),

						Builder.node( 'button', { className: 'ui-button uib-fake-file', type: 'button' }, [

							Builder._text('Browse...')

						])

				])

			);

			// here, get the dimensions of the fake buton and add hover class if pointer is over it
			var span = $($(e).parentNode).down('.ui-button');

			var sd = $(span).getDimensions();

			var sp = $(span).positionedOffset();

			var sb = sp.top + sd.height;

			var sr = sp.left + sd.width;

			// make the file input browse button stick to the mouse pointer
			var fd = $(e).getDimensions();

			var pp = $($(e).parentNode).positionedOffset();

			$($(e).parentNode).observe( 'mousemove', ( function (m) {

				var mx = $(m).pointerX() - pp.left;

				var my = $(m).pointerY() - pp.top;

				var x = mx - (fd.width - 30);

				var y = my - (fd.height / 2);

				$(e).setStyle( { top: y + 'px', left: x + 'px' });

				if ( ( my > sp.top && my < sb ) && ( mx > sp.left && mx < sr ) ) {

					$(span).addClassName('uib-hover');

				} else {

					$(span).removeClassName('uib-hover');

				}

			}).bindAsEventListener(this));

			$($(e).parentNode).observe( 'mouseout', ( function (o) {

				$(span).removeClassName('uib-hover');

			}).bindAsEventListener(this));

			$(e).observe('change', ( function (i) {

				$($(e).parentNode).down('input[type=text]').value = $(e).value;

			}).bindAsEventListener(this));

		});

	}

});

document.observe('dom:loaded', function () { new nk_form_functions(); });

