/**
 * jQuery Plugin SuperFlyDOM v0.9g
 *
 * Create DOM elements on the fly and automatically append or prepend them to another DOM object.
 * There are also template functions (tplAppend and tplPrepend) that can take a JSON-formatted
 * complex HTML structure, apply a dataset, and therefore add siblings way faster
 * 
 * This plugin is built off of FlyDom 3.0.8, by dohpaz
 * [http://dohpaz.mine.nu/jquery/jquery.flydom.html], who was inspired by "Oslow"
 * [http://mg.to/2006/02/27/easy-dom-creation-for-jquery-and-prototype#comment-176],
 * and since I could not get dohpaz code to work with my template (and since dohpaz
 * could not get Oslow's code to work), and neither Michael Geary's code nor Sean's
 * [http://www.pinkblack.org/itblog/?page_id=22] code were jQuery style and chainable,
 * and I wanted a ton of features anyway, while retaining a small code base, I decided
 * to rip apart, clean up (JSLint),and add features to their plugins. My hope is that
 * this version will be easier to understand, more forgiving and flexible, and maintain
 * with future versions of the fantastic framework which is jQuery.
 *
 * Note: For event attaching using the liveQuery plugin is highly recommended.
 *
 * Copyright (c) 2007 Charles Phillips [charles at doublerebel dot com]
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * @version	 $Id: jquery.superflydom-0.9g.js 9 2007-08-27 00:02:34 polyrhythmic $
 *
 * @author	  Charles Phillips [charles at doublerebel dot com]
 * @copyright   (C) 2007. All rights reserved.
 *
 * @license	 http://www.opensource.org/licenses/mit-license.php
 * @license	 http://www.opensource.org/licenses/gpl-license.php
 *
 * @package	 jQuery Plugins
 * @subpackage  SuperFlyDOM
 *
 * @todo		 (dohpaz): Cache basic elements that are created, and if an already existing basic element is
 *			 asked to be created an additional time, use a copy of the cached element to build from.
 *			 (Charles): If dohpaz accomplishes this I will be happy to merge it with my code fork.
 * 
 */

/**
 * Create DOM elements on the fly and automatically append them to the current DOM obejct
 *
 * @uses	jQuery
 *
 * @param   string  element - The name of the DOM element to create (i.e., img, table, a, etc)
 * @param   object  attrs   - An optional object of attributes to apply to the element
 * @param   string  text    - An optional string for text node to prepend to element
 * @param   array   content - An optional array of content (or element children) to append to element
 *
 * @return  jQuery  element - The jQuery object representing the new element
 *
 * @since   FlyDom 1.0
 */

( function($) {
	var el;
	if ($.elHash === undefined) { //If there is no jQuery global hash yet defined,
		var elArray, elHash = {}; //Define hash table of HTML 4.01 DOM Elements, excluding deprecated elements.
		elArray = "a|abbr|acronym|address|area|b|base|bdo|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|dt|em|fieldset|form|frame|frameset|h1-h6|head|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|meta|noframes|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var".split("|"); //packed hash
		for (var i = 0; i < elArray.length; i++) { elHash[elArray[i]] = true; } //Process hash
		$.elHash = elHash; //Set jQuery global hash
	}
	if ($.browser.msie) { //From Dean Edwards IE7 fixes [http://dean.edwards.name] I can't believe I have to do this, damn you IE
		Array.prototype.unshift = function() {
			var a = Array.prototype.concat.call(Array.prototype.slice.apply(arguments, [0]), this), i = a.length;
			while (i--) { this[i] = a[i]; }
			return this.length;
		}
	}
	$.fn.extend({
		createAppend: function() {
			if (arguments.length === 0) { return this; } //If nothing to process, move along!
			var ie, pEl, elH = $.elHash, arg1 = arguments[0], arg2 = arguments[1], a = 1;
			pEl = this[0] || this; //Parent element may be either jQuery Object or DOM element
			if (typeof arg1 === "number") { arg1 = String(arg1); } //Pure numbers cannot be made into textNodes, nor can you run RegExp's or .constructor against them.  I learned this the hard way.
			if (typeof arg1 === "string") { //We should have a string by now, or the input JSON was improperly formatted.
				if (arg1 in elH) { //If first argument is valid HTML Element
					ie = $.browser.msie;
					el = (ie && arg1 === 'input') ? '<input type="' + arg2.type + '" />': arg1; //Fix input for ie. REQUIRES attribute type.
					el = document.createElement(el);
					if (ie && pEl.nodeName.toLowerCase() === "table" && el.nodeName.toLowerCase() === "tr") { //Fix table/tbody for ie.
						pEl = pEl.parentNode.getElementsByTagName('tbody')[0] || pEl.appendChild(document.createElement('tbody')); // Create a new tbody
					}
					el = pEl.appendChild(el); // Add the element directly to the parentElement
					if (arg2.constructor === Object) { //if element's sibling is Attributes Object, process with jQuery
						for (attr in arg2) { $.attr(el, attr, arg2[attr]); }
						a++;
					}
					if (arguments.length > a) { //If element has more objects in arguments[] than we have processed
						if (arguments[a].constructor === Array){ //and the next object is an array, it is element's children
							el = $.fn.createAppend.apply($(el), arguments[a]); //recursively apply
							a++;
						}
					}
				} else if (arg1.match(/(<\S[^><]*>)|(&.+;)/g) !== null &&
						 arg1.tagName.toUpperCase() !== 'TEXTAREA') { //Check to see if TextNode is actually mixed HTML, but not textarea
						pEl.innerHTML += arg1; //Append HTML
						el = pEl; //We have no information about what could be in that HTML, so return parent
				} else { el = pEl.appendChild(document.createTextNode(arg1)); } //Otherwise just append simple TextNode
			} else { } //There should be no else.  Todo: Add error catching with throw/catch on string instead of if - Instead of hashing?
			if (arguments.length > a) { //If element has unprocessed siblings
				el = $.fn.createAppend.apply($(pEl), Array.prototype.slice.call(arguments, a)); //Process siblings (sliced arguments array) and append to parent element
			}
			return $(el); //We like chaining
		},
		
		createPrepend: function() {
			var al = arguments.length;
			if (al === 0) { return this; } //If nothing to process, move along!
			var elH = $.elHash, ie, pEl, hCN = this[0].hasChildNodes(), arg_l, arg = [];
			arg_l = arg.push(arguments[al-1]); //Start stacking our queue
			pEl = this[0] || this; //Parent element may be either jQuery Object or DOM element
			if (arg[0].constructor === Array) { //If element to prepend has children, add to bottom of queue
				arg_l = arg.unshift(arguments[al - 1 - arg_l]);
			}
			if (arg[0].constructor === Object) { //if element to prepend has attributes, add to queue
				arg_l = arg.unshift(arguments[al - 1 - arg_l]);
			}
			if (typeof arg[0] === "number") { arg[0] = String(arg[0]); } //Pure numbers cannot be made into textNodes, nor can you run RegExp's or .constructor against them.  I learned this the hard way.
			if (typeof arg[0] === "string") { //We should have a string by now, or the input JSON was improperly formatted.
				if (arg[0] in elH) { //If first argument is valid HTML Element
					ie = $.browser.msie;
					el = (ie && arg[0] === 'input') ? '<input type="' + arg[1].type + '" />': arg[0]; //Fix input for ie. REQUIRES attribute type.
					arg.shift();
					el = document.createElement(el);
					if (ie && pEl.nodeName.toLowerCase() === "table" && el.nodeName.toLowerCase() === "tr") { //Fix table/tbody for ie.
						pEl = pEl.parentNode.getElementsByTagName('tbody')[0] || pEl.appendChild(document.createElement('tbody')); // Create a new tbody
					}
					if (hCN) { el = pEl.insertBefore(el, pEl.firstChild); } //If parent already has child nodes, add new element before them
					else { el = pEl.appendChild(el); } // Otherwise add the element directly to the parentElement
					if (arg[0].constructor === Object) {  //if element's sibling is Attributes Object, process with jQuery
						for (attr in arg[0]) { $.attr(el, attr, arg[0][attr]); }
						arg.shift();
					}
					if (arg[0] !== undefined && arg[0].constructor === Array) { //If there are still elements in the queue, and it's an array
						el = $.fn.createPrepend.apply($(el), arg[0]); //Then recursively prepend the children
					}
				} else if (arg[0].match(/(<\S[^><]*>)|(&.+;)/g) !== null &&
						 arg[0].tagName.toUpperCase() !== 'TEXTAREA') { //Check to see if TextNode is actually mixed HTML, but not textarea
						pEl.innerHTML = arg.pop() + pEl.innerHTML; //Prepend HTML
						el = pEl; //We have no information about what could be in that HTML, so return parent
				} else {
					el = document.createTextNode(arg[0]); //Otherwise just create simple TextNode
					el = (hCN) ? pEl.insertBefore(el, pEl.firstChild) : pEl.appendChild(el); //If parent already has child nodes, add new element before them
				}
			} else { } //There should be no else.  Todo: Add error catching with throw/catch on string instead of if - Instead of hashing?
			if (al > arg_l) { //If element has unprocessed siblings
				el = $.fn.createPrepend.apply($(pEl), Array.prototype.slice.call(arguments, 0, -arg_l)); //Process siblings (sliced arguments array) and prepend to parent element
			}
			return $(el);
		},

		tplAppend: function(json, tpl) {
			return $.fn.createAppend.apply(this, tpl.call(json)); // Return ourself for chaining
		},
		
		tplPrepend: function(json, tpl) {
			return $.fn.createPrepend.apply(this, tpl.call(json)); // Return ourself for chaining
		}
	});
})(jQuery);


//function for showing/hiding modal window
	(function($)
	
	{
	    $.modal=function(data,
	    options)
	    {
	        return $.modal.impl.init(data,
	        options);
	    }
	    ;$.modal.close=function()
	    {
	        $.modal.impl.close(true);
	    }
	    ;$.fn.modal=function(options)
	    {
	        return $.modal.impl.init(this,
	        options);
	    }
	    ;$.modal.defaults=
	    {
	        overlay:50,
	        overlayId:'modalOverlay',
	        overlayCss:
	        {
	        },
	        containerId:'modalContainer',
	        containerCss:
	        {
	        },
	        close:false,
	        closeTitle:'Close',
	        closeClass:'modalClose',
	        persist:false,
	        onOpen:null,
	        onShow:null,
	        onClose:null
	    }
	    ;$.modal.impl=
	    {
	        opts:null,
	        dialog:
	        {
	        },
	        init:function(data,
	        options)
	        {
	            if(this.dialog.data)
	            {
	                return false;
	            }
	            this.opts=$.extend(
	            {
	            },
	            $.modal.defaults,
	            options);if(typeof data=='object')
	            {
	                data=data instanceof jQuery?data:$(data);if(data.parent().parent().size()>0)
	                {
	                    this.dialog.parentNode=data.parent();if(!this.opts.persist)
	                    {
	                        this.dialog.original=data.clone(true);
	                    }
	                }
	            }
	            else if(typeof data=='string'||typeof data=='number')
	            {
	                data=$('<div>').html(data);
	            }
	            else
	            {
	                if(console)
	                {
	                    console.log('SimpleModal Error: Unsupported data type: '+typeof data);
	                }
	                return false;
	            }
	            this.dialog.data=data.addClass('modalData');data=null;this.create();this.open();if($.isFunction(this.opts.onShow))
	            {
	                this.opts.onShow.apply(this,
	                [
	                    this.dialog
	                ]
	                );
	            }
	            return this;
	        },
	        create:function()
	        {
	            this.dialog.overlay=$('<div>').attr('id',
	            this.opts.overlayId).addClass('modalOverlay').css($.extend(this.opts.overlayCss,
	            {
	                opacity:this.opts.overlay/100,
	                height:'100%',
	                width:'100%',
	                position:'fixed',
	                left:0,
	                top:0,
	                zIndex:3000
	            }
	            )).hide().appendTo('body');this.dialog.container=$('<div>').attr('id',
	            this.opts.containerId).addClass('modalContainer').css($.extend(this.opts.containerCss,
	            {
	                position:'fixed',
	                zIndex:3100
	            }
	            )).append(this.opts.close?'<a class="modalCloseImg '+this.opts.closeClass
	+'" title="'+this.opts.closeTitle+'"></a>':'').hide().appendTo('body');
				if($.browser.msie&&($.browser.version<7))
	            {
	                this.fixIE();
	            }
	            this.dialog.container.append(this.dialog.data.hide());
	        },
	        bindEvents:function()
	        {
	            var modal=this;$('.submitBtn').click(function(e)
	            {
	                e.preventDefault();modal.close();
	            }
	            );
	        },
	        unbindEvents:function()
	        {
	            $('.'+this.opts.closeClass).unbind('click');
	        },
	        fixIE:function()
	        {
	            var wHeight=$(document.body).height()+'px';var wWidth=$(document.body).width()+'px';this.dialog.overlay.css(
	            {
	                position:'absolute',
	                height:wHeight,
	                width:wWidth
	            }
	            );this.dialog.container.css(
	            {
	                position:'absolute'
	            }
	            );this.dialog.iframe=$('<iframe src="javascript:false;">').css($.extend(this.opts.iframeCss,
	            {
	                opacity:0,
	                position:'absolute',
	                height:wHeight,
	                width:wWidth,
	                zIndex:1000,
	                width:'100%',
	                top:0,
	                left:0
	            }
	            )).hide().appendTo('body');
	        },
	        open:function()
	        {
	            if(this.dialog.iframe)
	            {
	                this.dialog.iframe.show();
	            }
	            if($.isFunction(this.opts.onOpen))
	            {
	                this.opts.onOpen.apply(this,
	                [
	                    this.dialog
	                ]
	                );
	            }
	            else
	            {
	                this.dialog.overlay.show();this.dialog.container.show();this.dialog.data.show();
	            }
	            this.bindEvents();
	        },
	        close:function(external)
	        {
	            if(!this.dialog.data)
	            {
	                return false;
	            }
	            if($.isFunction(this.opts.onClose)&&!external)
	            {
	                this.opts.onClose.apply(this,
	                [
	                    this.dialog
	                ]
	                );
	            }
	            else
	            {
	                if(this.dialog.parentNode)
	                {
	                    if(this.opts.persist)
	                    {
	                        this.dialog.data.hide().appendTo(this.dialog.parentNode);
	                    }
	                    else
	                    {
	                        this.dialog.data.remove();this.dialog.original.appendTo(this.dialog.parentNode);
	                    }
	                }
	                else
	                {
	                    this.dialog.data.remove();
	                }
	                this.dialog.container.remove();this.dialog.overlay.remove();if(this.dialog.iframe)
	                {
	                    this.dialog.iframe.remove();
	                }
	                this.dialog=
	                {
	                }
	                ;
	            }
	            this.unbindEvents();
	        }
	    }
	    ;
	}
	)(jQuery);
	
	
	