/*!
 * jQuery Templates Plugin Library v1.1.0
 * http://www.ivorycity.com/blog/jquery-template-plugin/
 *
 * Copyright (c) 2009 Michael Collins
 * Dual licensed under the MIT and GPL licenses.
 * See MIT-LICENSE.txt and GPL-LICENSE.txt
 *
 */
 
jQuery.fn.extend( {

	render: function( values, options )
	{
		var re_cache = {};
		var clone_list = null;
		var selector_re = new RegExp('[\'"](.+)[\'"]','mg');

		options = options || [];
		values  = $.makeArray(values);

		this.each( function (i)
		{
			var render = function (tvals,tmplnode,options) 
			{
				var tmp_node = $("<div></div>").append( tmplnode.clone() );
				$.each(tvals, function (k,v)
				{
					k = ''+k;

					//jquery selector or cloner, not string replace
					if ( k.indexOf( '$(' )==0 || k.indexOf( '@(' )==0 )
					{
						var m = selector_re.exec(k);

						if (m[1])
						{
							tmp_node.find(m[1]).render(v,{clone:k.indexOf('@')==0?true:false});
						}
						return;
					}
				});

				var context = '';
				var tmpl = tmp_node.html().replace(/%7B/ig,'{').replace(/%7D/ig,'}');
				var kv_iterator = function(k,v)
				{
					replacement = context + k;

					if (!re_cache[replacement])
					{
						if ( v!=null && typeof v == 'object' || typeof v == 'array' )
						{
							var tmp_context = context;
							context = replacement+'.'; 
							$.each(v,kv_iterator);
							context = tmp_context;
							return;
						}

						re_cache[replacement] = new RegExp('{'+replacement+'}', 'gm'); 
					}

					var re = re_cache[replacement];
					tmpl = tmpl.replace( re, v );	
				}; // end kv_iterator


				$.each(tvals, kv_iterator);

				var node = $(tmpl);

				if (options['beforeUpdate']) 
				{
					options['beforeUpdate'](node);		
				}

				if (options['clone'])
				{
					tmplnode.after(node);
				}
				else	
				{
					tmplnode.replaceWith(node);
				}

				if (options['afterUpdate']) 
				{
					options['afterUpdate'](node);
				}		

				return node;
			}; // end render

			var node = $(this);

			if (options['preserve_template'])
			{
				options['clone'] = true;
			}

			if (options['clone'])
			{
				values = $.makeArray(values);
				$(values.reverse()).each( function()
				{ 
					var newnode = render(this,node,options); 

					if( !clone_list )
					{
						clone_list = $(newnode);
					}
					else
					{
						clone_list.push(newnode[0]);
					}
				});

				if (!options['preserve_template'])
				{
					$(this).remove();
				}				
			}
			else
			{
				var repl = (values[i] || values[values.length-1]);
				render(repl,node,options);
			}

		});
	
		if (clone_list)
		{
			return this.pushStack(clone_list, 'render', this.selector );
		}
		else
		{
			return this;
		}
	}
});

/*
 * jqModal - Minimalist Modaling with jQuery
 *   (http://dev.iceburg.net/jquery/jqModal/)
 *
 * Copyright (c) 2007,2008 Brice Burgess <bhb@iceburg.net>
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 * 
 * $Version: 03/01/2009 +r14
 */
(function($) {
$.fn.jqm=function(o){
var p={
overlay: 50,
overlayClass: 'jqmOverlay',
closeClass: 'jqmClose',
trigger: '.jqModal',
ajax: F,
ajaxText: '',
target: F,
modal: F,
toTop: F,
onShow: F,
onHide: F,
onLoad: F
};
return this.each(function(){if(this._jqm)return H[this._jqm].c=$.extend({},H[this._jqm].c,o);s++;this._jqm=s;
H[s]={c:$.extend(p,$.jqm.params,o),a:F,w:$(this).addClass('jqmID'+s),s:s};
if(p.trigger)$(this).jqmAddTrigger(p.trigger);
});};

$.fn.jqmAddClose=function(e){return hs(this,e,'jqmHide');};
$.fn.jqmAddTrigger=function(e){return hs(this,e,'jqmShow');};
$.fn.jqmShow=function(t){return this.each(function(){t=t||window.event;$.jqm.open(this._jqm,t);});};
$.fn.jqmHide=function(t){return this.each(function(){t=t||window.event;$.jqm.close(this._jqm,t)});};

$.jqm = {
hash:{},
open:function(s,t){var h=H[s],c=h.c,cc='.'+c.closeClass,z=(parseInt(h.w.css('z-index'))),z=(z>0)?z:3000,o=$('<div></div>').css({height:'100%',width:'100%',position:'fixed',left:0,top:0,'z-index':z-1,opacity:c.overlay/100});if(h.a)return F;h.t=t;h.a=true;h.w.css('z-index',z);
 if(c.modal) {if(!A[0])L('bind');A.push(s);}
 else if(c.overlay > 0)h.w.jqmAddClose(o);
 else o=F;

 h.o=(o)?o.addClass(c.overlayClass).prependTo('body'):F;
 if(ie6){$('html,body').css({height:'100%',width:'100%'});if(o){o=o.css({position:'absolute'})[0];for(var y in {Top:1,Left:1})o.style.setExpression(y.toLowerCase(),"(_=(document.documentElement.scroll"+y+" || document.body.scroll"+y+"))+'px'");}}

 if(c.ajax) {var r=c.target||h.w,u=c.ajax,r=(typeof r == 'string')?$(r,h.w):$(r),u=(u.substr(0,1) == '@')?$(t).attr(u.substring(1)):u;
  r.html(c.ajaxText).load(u,function(){if(c.onLoad)c.onLoad.call(this,h);if(cc)h.w.jqmAddClose($(cc,h.w));e(h);});}
 else if(cc)h.w.jqmAddClose($(cc,h.w));

 if(c.toTop&&h.o)h.w.before('<span id="jqmP'+h.w[0]._jqm+'"></span>').insertAfter(h.o);	
 (c.onShow)?c.onShow(h):h.w.show();e(h);return F;
},
close:function(s){var h=H[s];if(!h.a)return F;h.a=F;
 if(A[0]){A.pop();if(!A[0])L('unbind');}
 if(h.c.toTop&&h.o)$('#jqmP'+h.w[0]._jqm).after(h.w).remove();
 if(h.c.onHide)h.c.onHide(h);else{h.w.hide();if(h.o)h.o.remove();} return F;
},
params:{}};
var s=0,H=$.jqm.hash,A=[],ie6=$.browser.msie&&($.browser.version == "6.0"),F=false,
i=$('<iframe src="javascript:false;document.write(\'\');" class="jqm"></iframe>').css({opacity:0}),
e=function(h){if(ie6)if(h.o)h.o.html('<p style="width:100%;height:100%"/>').prepend(i);else if(!$('iframe.jqm',h.w)[0])h.w.prepend(i); f(h);},
f=function(h){try{$(':input:visible',h.w)[0].focus();}catch(_){}},
L=function(t){$()[t]("keypress",m)[t]("keydown",m)[t]("mousedown",m);},
m=function(e){var h=H[A[A.length-1]],r=(!$(e.target).parents('.jqmID'+h.s)[0]);if(r)f(h);return !r;},
hs=function(w,t,c){return w.each(function(){var s=this._jqm;$(t).each(function() {
 if(!this[c]){this[c]=[];$(this).click(function(){for(var i in {jqmShow:1,jqmHide:1})for(var s in this[i])if(H[this[i][s]])H[this[i][s]].w[i](this);return F;});}this[c].push(s);});});};
})(jQuery);

/*
 * jqDnR - Minimalistic Drag'n'Resize for jQuery.
 *
 * Copyright (c) 2007 Brice Burgess <bhb@iceburg.net>, http://www.iceburg.net
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * $Version: 2007.08.19 +r2
 */

(function($){
$.fn.jqDrag=function(h){return i(this,h,'d');};
$.fn.jqResize=function(h){return i(this,h,'r');};
$.jqDnR={dnr:{},e:0,
drag:function(v){
 if(M.k == 'd')E.css({left:M.X+v.pageX-M.pX,top:M.Y+v.pageY-M.pY});
 else E.css({width:Math.max(v.pageX-M.pX+M.W,0),height:Math.max(v.pageY-M.pY+M.H,0)});
  return false;},
stop:function(){E.css('opacity',M.o);$().unbind('mousemove',J.drag).unbind('mouseup',J.stop);}
};
var J=$.jqDnR,M=J.dnr,E=J.e,
i=function(e,h,k){return e.each(function(){h=(h)?$(h,e):e;
 h.bind('mousedown',{e:e,k:k},function(v){var d=v.data,p={};E=d.e;
 // attempt utilization of dimensions plugin to fix IE issues
 if(E.css('position') != 'relative'){try{E.position(p);}catch(e){}}
 M={X:p.left||f('left')||0,Y:p.top||f('top')||0,W:f('width')||E[0].scrollWidth||0,H:f('height')||E[0].scrollHeight||0,pX:v.pageX,pY:v.pageY,k:d.k,o:E.css('opacity')};
 E.css({opacity:0.8});$().mousemove($.jqDnR.drag).mouseup($.jqDnR.stop);
 return false;
 });
});},
f=function(k){return parseInt(E.css(k))||false;};
})(jQuery);

$.extend({URLEncode: function (c) {
    var o = '';
    var x = 0;
    c = c.toString();
    var r = /(^[a-zA-Z0-9_.]*)/;
    
    while (x < c.length) {
        var m = r.exec(c.substr(x));
        if (m !== null && m.length > 1 && m[1] != '') {
            o += m[1];
            x += m[1].length;
        } else {
            if (c[x] === ' ') {
                o += '+';
            } else {
                var d = c.charCodeAt(x);
                var h = d.toString(16);
                o += '%' + (h.length < 2 ? '0': '') + h.toUpperCase();
            }
            x++;
        }
    }
    return o;
},
URLDecode: function (s) {
    var o = s;
    var binVal, t;
    var r = /(%[^%]{2})/;
    while ((m = r.exec(o)) !== null && m.length > 1 && m[1] != '') {
        b = parseInt(m[1].substr(1), 16);
        t = String.fromCharCode(b);
        o = o.replace(m[1], t);
    }
    return o;
}
});

/**
 * labs_json Script by Giraldo Rosales.
 * Version 1.0
 * Visit www.liquidgear.net for documentation and updates.
 *
 *
 * Copyright (c) 2009 Nitrogen Design, Inc. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 **/
 
/**
 * HOW TO USE
 * ==========
 * Encode:
 * var obj = {};
 * obj.name	= "Test JSON";
 * obj.type	= "test";
 * $.json.encode(obj); //output: {"name":"Test JSON", "type":"test"}
 * 
 * Decode:
 * $.json.decode({"name":"Test JSON", "type":"test"}); //output: object
 * 
 */
 
jQuery.json = {
    encode: function (value, replacer, space) {
		var i;
		gap = '';
		var indent = '';
		
		if (typeof space === 'number') {
			for (i = 0; i < space; i += 1) {
				indent += ' ';
			}
			
		} else if (typeof space === 'string') {
			indent = space;
		}
		
		rep = replacer;
		if (replacer && typeof replacer !== 'function' &&
				(typeof replacer !== 'object' ||
				 typeof replacer.length !== 'number')) {
			throw new Error('JSON.encode');
		}
		
		return this.str('', {'': value});
    },
    
    decode: function (text, reviver) {
		var j;
		var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
		
		function walk(holder, key) {
			var k, v, value = holder[key];
			
			if (value && typeof value === 'object') {
				for (k in value) {
					if (Object.hasOwnProperty.call(value, k)) {
						v = walk(value, k);
						if (v !== undefined) {
							value[k] = v;
						} else {
							delete value[k];
						}
					}
				}
			}
			return reviver.call(holder, key, value);
		}
		
		cx.lastIndex = 0;
		
		if (cx.test(text)) {
			text = text.replace(cx, function (a) {
				return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
			});
		}
		
		if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
			j = eval('(' + text + ')');
			return typeof reviver === 'function' ? walk({'': j}, '') : j;
		}
		
		throw new SyntaxError('JSON.parse');
	},
	
    f: function (n) {
        return n < 10 ? '0' + n : n;
    },
	
	DateToJSON: function (key) {
		return this.getUTCFullYear() + '-' + this.f(this.getUTCMonth() + 1) + '-' + this.f(this.getUTCDate())      + 'T' + this.f(this.getUTCHours())     + ':' + this.f(this.getUTCMinutes())   + ':' + this.f(this.getUTCSeconds())   + 'Z';
	},
	
	StringToJSON: function (key) {
		return this.valueOf();
    },
    
    quote: function (string) {
        var meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
        var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
        
        escapable.lastIndex = 0;
        return escapable.test(string) ?
            '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c :
                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' :
            '"' + string + '"';
    },
    
    str: function (key, holder) {
        var indent = '', gap = '', i, k, v, length, mind = gap, partial, value = holder[key];
        
        if (value && typeof value === 'object') {
            switch ((typeof value)) {
            case 'date':
                this.DateToJSON(key);
                break;
            default:
                this.StringToJSON(key);
                break;
            }
        }
        
        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }
        switch (typeof value) {
        case 'string':
            return this.quote(value);
        case 'number':
            return isFinite(value) ? String(value) : 'null';
        case 'boolean':
        case 'null':
            return String(value);
        case 'object':
            if (!value) {
                return 'null';
            }
            gap += indent;
            partial = [];
				
            if (Object.prototype.toString.apply(value) === '[object Array]') {
                length = value.length;
                
                for (i = 0; i < length; i += 1) {
                    partial[i] = this.str(i, value) || 'null';
                }
	
                v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }
                
            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    k = rep[i];
                    if (typeof k === 'string') {
                        v = this.str(k, value);
                        if (v) {
                            partial.push(this.quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {
                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = this.str(k, value);
                        if (v) {
                            partial.push(this.quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

            v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                        mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
		}
	}
};

