jQuery.fn.extend({
	everyTime: function(interval, label, fn, times, belay) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, times, belay);
		});
	},
	oneTime: function(interval, label, fn) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, 1);
		});
	},
	stopTime: function(label, fn) {
		return this.each(function() {
			jQuery.timer.remove(this, label, fn);
		});
	}
});

jQuery.extend({
	timer: {
		guid: 1,
		global: {},
		regex: /^([0-9]+)\s*(.*s)?$/,
		powers: {
			// Yeah this is major overkill...
			'ms': 1,
			'cs': 10,
			'ds': 100,
			's': 1000,
			'das': 10000,
			'hs': 100000,
			'ks': 1000000
		},
		timeParse: function(value) {
			if (value == undefined || value == null)
				return null;
			var result = this.regex.exec(jQuery.trim(value.toString()));
			if (result[2]) {
				var num = parseInt(result[1], 10);
				var mult = this.powers[result[2]] || 1;
				return num * mult;
			} else {
				return value;
			}
		},
		add: function(element, interval, label, fn, times, belay) {
			var counter = 0;
			
			if (jQuery.isFunction(label)) {
				if (!times) 
					times = fn;
				fn = label;
				label = interval;
			}
			
			interval = jQuery.timer.timeParse(interval);

			if (typeof interval != 'number' || isNaN(interval) || interval <= 0)
				return;

			if (times && times.constructor != Number) {
				belay = !!times;
				times = 0;
			}
			
			times = times || 0;
			belay = belay || false;
			
			if (!element.$timers) 
				element.$timers = {};
			
			if (!element.$timers[label])
				element.$timers[label] = {};
			
			fn.$timerID = fn.$timerID || this.guid++;
			
			var handler = function() {
				if (belay && this.inProgress) 
					return;
				this.inProgress = true;
				if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
					jQuery.timer.remove(element, label, fn);
				this.inProgress = false;
			};
			
			handler.$timerID = fn.$timerID;
			
			if (!element.$timers[label][fn.$timerID]) 
				element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);
			
			if ( !this.global[label] )
				this.global[label] = [];
			this.global[label].push( element );
			
		},
		remove: function(element, label, fn) {
			var timers = element.$timers, ret;
			
			if ( timers ) {
				
				if (!label) {
					for ( label in timers )
						this.remove(element, label, fn);
				} else if ( timers[label] ) {
					if ( fn ) {
						if ( fn.$timerID ) {
							window.clearInterval(timers[label][fn.$timerID]);
							delete timers[label][fn.$timerID];
						}
					} else {
						for ( var fn in timers[label] ) {
							window.clearInterval(timers[label][fn]);
							delete timers[label][fn];
						}
					}
					
					for ( ret in timers[label] ) break;
					if ( !ret ) {
						ret = null;
						delete timers[label];
					}
				}
				
				for ( ret in timers ) break;
				if ( !ret ) 
					element.$timers = null;
			}
		}
	}
});

if (jQuery.browser.msie)
	jQuery(window).one("unload", function() {
		var global = jQuery.timer.global;
		for ( var label in global ) {
			var els = global[label], i = els.length;
			while ( --i )
				jQuery.timer.remove(els[i], label);
		}
	});



/**
 * jQuery.query - Query String Modification and Creation for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2008/05/28
 *
 * @author Blair Mitchelmore
 * @version 2.0.0
 *
 **/
new function(settings) { 
  // Various Settings
  var $separator = settings.separator || '&';
  var $spaces = settings.spaces === false ? false : true;
  var $suffix = settings.suffix === false ? '' : '[]';
  var $prefix = settings.prefix === false ? false : true;
  var $hash = $prefix ? settings.hash === true ? "#" : "?" : "";
  
  jQuery.query = new function() {
    var is = function(o, t) {
      return o != undefined && o !== null && (!!t ? o.constructor == t : true);
    };
    var parse = function(path) {
      var m, rx = /\[([^[]*)\]/g, match = /^(\S+?)(\[\S*\])?$/.exec(path), base = match[1], tokens = [];
      while (m = rx.exec(match[2])) tokens.push(m[1]);
      return [base, tokens];
    };
    var set = function(target, tokens, value) {
      var o, token = tokens.shift();
      if (typeof target != 'object') target = null;
      if (token === "") {
        if (!target) target = [];
        if (is(target, Array)) {
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        } else if (is(target, Object)) {
          var i = 0;
          while (target[i++] != null);
          target[--i] = tokens.length == 0 ? value : set(target[i], tokens.slice(0), value);
        } else {
          target = [];
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        }
      } else if (token && token.match(/^\s*[0-9]+\s*$/)) {
        var index = parseInt(token, 10);
        if (!target) target = [];
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else if (token) {
        var index = token.replace(/^\s*|\s*$/g, "");
        if (!target) target = {};
        if (is(target, Array)) {
          var temp = {};
          for (var i = 0; i < target.length; ++i) {
            temp[i] = target[i];
          }
          target = temp;
        }
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else {
        return value;
      }
      return target;
    };
    
    var queryObject = function(a) {
      var self = this;
      self.keys = {};
      
      if (a.queryObject) {
        jQuery.each(a.get(), function(key, val) {
          self.SET(key, val);
        });
      } else {
        jQuery.each(arguments, function() {
          var q = "" + this;
          q = q.replace(/^[?#]/,''); // remove any leading ? || #
          q = q.replace(/[;&]$/,''); // remove any trailing & || ;
          if ($spaces) q = q.replace(/[+]/g,' '); // replace +'s with spaces
          
          jQuery.each(q.split(/[&;]/), function(){
            var key = this.split('=')[0];
            var val = this.split('=')[1];
            
            if (!key) return;
            
            if (/^[+-]?[0-9]+\.[0-9]*$/.test(val)) // simple float regex
              val = parseFloat(val);
            else if (/^[+-]?[0-9]+$/.test(val)) // simple int regex
              val = parseInt(val, 10);
            
            val = (!val && val !== 0) ? true : val;
            
            if (val !== false && val !== true && typeof val != 'number')
              val = decodeURIComponent(val);
            
            self.SET(key, val);
          });
        });
      }
      return self;
    };
    
    queryObject.prototype = {
      queryObject: true,
      has: function(key, type) {
        var value = this.get(key);
        return is(value, type);
      },
      GET: function(key) {
        if (!is(key)) return this.keys;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        while (target != null && tokens.length != 0) {
          target = target[tokens.shift()];
        }
        return target || "";
      },
      get: function(key) {
        var target = this.GET(key);
        if (is(target, Object))
          return jQuery.extend(true, {}, target);
        else if (is(target, Array))
          return target.slice(0);
        return target;
      },
      SET: function(key, val) {
        var value = !is(val) ? null : val;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        this.keys[base] = set(target, tokens.slice(0), value);
        return this;
      },
      set: function(key, val) {
        return this.copy().SET(key, val);
      },
      REMOVE: function(key) {
        return this.SET(key, null).COMPACT();
      },
      remove: function(key) {
        return this.copy().REMOVE(key);
      },
      EMPTY: function() {
        var self = this;
        jQuery.each(self.keys, function(key, value) {
          delete self.keys[key];
        });
        return self;
      },
      empty: function() {
        return this.copy().EMPTY();
      },
      copy: function() {
        return new queryObject(this);
      },
      COMPACT: function() {
        function build(orig) {
          var obj = typeof orig == "object" ? is(orig, Array) ? [] : {} : orig;
          if (typeof orig == 'object') {
            function add(o, key, value) {
              if (is(o, Array))
                o.push(value);
              else
                o[key] = value;
            }
            jQuery.each(orig, function(key, value) {
              if (!is(value)) return true;
              add(obj, key, build(value));
            });
          }
          return obj;
        }
        this.keys = build(this.keys);
        return this;
      },
      compact: function() {
        return this.copy().COMPACT();
      },
      toString: function() {
        var i = 0, queryString = [], chunks = [], self = this;
        var addFields = function(arr, key, value) {
          if (!is(value) || value === false) return;
          var o = [key];
          if (value !== true) {
            o.push("=");
            o.push(encodeURIComponent(value));
          }
          arr.push(o.join(""));
        };
        var build = function(obj, base) {
          var newKey = function(key) {
            return !base || base == "" ? [key].join("") : [base, "[", key, "]"].join("");
          };
          jQuery.each(obj, function(key, value) {
            if (typeof value == 'object') 
              build(value, newKey(key));
            else
              addFields(chunks, newKey(key), value);
          });
        };
        
        build(this.keys);
        
        if (chunks.length > 0) queryString.push($hash);
        queryString.push(chunks.join($separator));
        
        return queryString.join("");
      }
    };
    
    return new queryObject(location.search, location.hash);
  };
}(jQuery.query || {}); // Pass in jQuery.query as settings object


// <copyright file="protomatter.navigation.js" company="Protomatter Web Solutions">
// Copyright (c) 2008 All Right Reserved
// </copyright>
// <author>Colin Mc Mahon</author>
// <email>colin@protomatter.co.uk</email>
// <date>2009-03-13</date>
// <requires>protomatter.global.js</requires>

/// <reference path="/admin/assets/script/jquery-1.2.3.js" />

/*
--------------------------------------------------
Script builds a hidden form error dialog and appends
it to the page, and exposes a 'show' method to 
present the dialog
--------------------------------------------------
*/
var FormError = {
    init: function()
    {
        if ($('#form-error').length == 0)
        {
            $('<div id="form-error">Please complete all required fields.</div>').dialog({
                modal: true,
                autoOpen: false,
                draggable: false,
                resizable: false,
                title: 'Form Error',
                dialogClass: 'error',
                height: 150,
                minHeight: 150,
                overlay: { opacity: 0.5, background: "black" },
                buttons: {
                    "OK": function()
                    {
                        $(this).dialog('close');
                    }
                }
            });
        }
    },
    show: function()
    {
        $('#form-error').dialog('open');
    }
};

/*
--------------------------------------------------
Script builds and displays a please wait dialog
diplayed when slow operations are underway, or a 
form save occurs, and exposes a 'show' method to 
present the dialog
--------------------------------------------------
*/
var Wait = {
    init: function()
    {
        if ($('#page-wait').length == 0)
        {
            $('<div id="page-wait">Please wait while the action completes.</div>').dialog({
                modal: true,
                autoOpen: false,
                draggable: false,
                resizable: false,
                title: 'Please Wait',
                dialogClass: 'please-wait',
                height: 150,
                minHeight: 150,
                overlay: { opacity: 0.5, background: "black" }
            });
        }
    },
    show: function()
    {
        $('#page-wait').dialog('open').oneTime(5000, function()
        {
            $(this).dialog('close');
        });
    }
};

/*
--------------------------------------------------
Script builds and displays a delete confirmation
diplayed when '.delete' elements are clicked, and
exposes a 'show' method to present the dialog
--------------------------------------------------
*/
var Delete = {
    init: function()
    {
        if ($('#page-delete').length == 0)
        {
            $('<div id="page-delete">Are you sure you want to delete this item.</div>').dialog({
                modal: true,
                autoOpen: false,
                draggable: false,
                resizable: false,
                title: 'Confirm Delete',
                dialogClass: 'confirm-delete',
                height: 150,
                minHeight: 150,
                overlay: { opacity: 0.5, background: "black" }
            });
        }
    },
    show: function(e)
    {
        e.preventDefault();
        var isForm;
        //        var thisForm;
        var lnkTarget;
        //        if ($(this).is("input[type='submit'], button[type='submit']"))
        //        {
        //            // this is an attempted form submission, get a ref to the form
        //            isForm = true;
        //            thisForm = $(this).parents("form").get(0);
        //        }
        //        else
        //        {
        //            isForm = false;
        lnkTarget = this.href;
        //        }
        $('#page-delete').dialog('option', 'buttons', {
            'Ok': function()
            {
                //if (isForm)
                //{
                //    $(thisForm).submit();
                //}
                //else
                //{
                     window.location.href = lnkTarget;
                //}
            },
            'Cancel': function()
            {
                $(this).dialog('close');
            }
        }).dialog('open');
    }
};

var Confirm = {
    init: function()
    {
        if ($('#page-confirm').length == 0)
        {
            $('<div id="page-confirm">Are you sure you want to continue.</div>').dialog({
                modal: true,
                autoOpen: false,
                draggable: false,
                resizable: false,
                title: 'Confirm Action',
                dialogClass: 'confirm-delete',
                height: 150,
                minHeight: 150,
                overlay: { opacity: 0.5, background: "black" }
            });
        }
    },
    show: function(e)
    {
        e.preventDefault();
        var isForm;
        var thisForm;
        var lnkTarget;
        var fName;
        var fVal;
        if ($(this).is("input[type='submit'], button[type='submit']"))
        {
            // this is an attempted form submission, get a ref to the form
            isForm = true;
            thisForm = $(this).parents("form").get(0);
            fName = $(this).attr("name");
            fVal = $(this).val();
        }
        else
        {
            isForm = false;
            lnkTarget = this.href;
        }
        $('#page-confirm').dialog('option', 'buttons', {
            'Ok': function()
            {
                if (isForm)
                {
                    // inject a hidden field to hold the button field
                    //$(thisForm).append('<input type="hidden" name="' + fName + '" value="' + fVal + '" />');
                    $(thisForm).submit()
                }
                else
                {
                    window.location.href = lnkTarget;
                }
            },
            'Cancel': function()
            {
                $(this).dialog('close');
            }
        }).dialog('open');
    }
};

/*
--------------------------------------------------
Initialise the above
--------------------------------------------------
*/
$(function()
{
    /* If there are .wait elements initialise and bind them */
    if ($('.wait').length > 0)
    {
        Wait.init();
        $('.wait').click(Wait.show);
    }
    /* If there are .delete elements initialise and bind them */
    if ($('.delete').length > 0)
    {
        Delete.init();
        $('.delete').click(Delete.show);
    }
    /* If there are .confirm elements initialise and bind them */
    if ($('.confirm').length > 0)
    {
        Confirm.init();
        $('.confirm').click(Confirm.show);
    }
});
// <copyright file="protomatter.navigation.js" company="Protomatter Web Solutions">
// Copyright (c) 2008 All Right Reserved
// </copyright>
// <author>Colin Mc Mahon</author>
// <email>colin@protomatter.co.uk</email>
// <date>2009-03-13</date>
// <requires>jquery.js, jquery.ui.js, protomatter.dialogs.js</requires>
// <todo></todo>

/*
--------------------------------------------------
Script loops through a jQuery array of form elements
and checks their value - if empty it adds a class
to their parent div, shows the form error dialog
and returns false
--------------------------------------------------
*/
var Validate = {
    init: function(fields)
    {
        var valid = true;
        $(fields).each(function()
        {
            var val = $(this).val();
            if (val === "" || val == "-1")
            {
                valid = false;
                $(this.pdiv).addClass('field-error');
            }
            else
            {
                $(this.pdiv).removeClass('field-error');
            }
        });
        if (!valid)
        {
            FormError.show();
        }
        return valid;
    }
};

/*
--------------------------------------------------
Validation initialisation routine - finds the calling
elements parent form and passes all '.required'
elements to the Validate function. If this returns
false the event that raised the ValidateForm is blocked
otherwise if the element that called is a button
it is disabled.
--------------------------------------------------
*/
ValidateForm = function(e)
{
    var pForm = $(this).parents('form')[0];
    var fValid = true;
    if (pForm && !$(pForm).hasClass('no-validation'))
    {
        var fields = $(pForm).find('.required');
        fValid = Validate.init(fields);
    }
    if (fValid === false)
    {
        e.preventDefault();
    }
    else
    {
        // Remove any error display
        $(".errorhandler-wrapper").remove();
        // Block the interface
        Wait.init();
        Wait.show();
    }
};

var HighlightFields = {
    init: function(in_fields, in_cmts)
    {
        $(function()
        {
            var fldAr = in_fields;
            var cmtAr = in_cmts;
            var parentDiv;
            var itemTitle;
            var itemLabel;
            for (var i = 0; i < fldAr.length; i++)
            {
                var tmpElem = fldAr[i];
                if (tmpElem.indexOf('file_') != -1 || tmpElem.indexOf('img_') != -1)
                {
                    tmpElem = tmpElem.split("__");
                    tmpElem = tmpElem[1];
                }
                parentDiv = $("#" + tmpElem).parents('div').get(0);
                $(parentDiv).addClass('field-error');
                if (cmtAr[i] !== "")
                {
                    itemTitle = cmtAr[i];
                }
                else
                {
                    itemTitle = "Error";
                }
                itemLabel = $(parentDiv).find("label, span.label").get(0);
                $(itemLabel).attr("title", itemTitle);
            }
        });
    }
};

/*
--------------------------------------------------
Script applies a class to the parent div of form
elements when focussed, but also stores a reference
to the div on the form element
--------------------------------------------------
*/
var FocusFields = {
    init: function()
    {
        $("input[type='text'], input[type='file'], textarea, select, input[type='checkbox'], input[type='radio']").each(function()
        {
            this.pdiv = $(this).parents("div").get(0);
            if (this.pdiv)
            {
                $(this).focus(function()
                {
                    $(this.pdiv).addClass('focus');
                });
                $(this).blur(function()
                {
                    $(this.pdiv).removeClass('focus');
                });
            }
        });
    }
};

/*
--------------------------------------------------
Initialise the above
--------------------------------------------------
*/
$(function()
{
    /* Set up the form fields */
    FocusFields.init();
    
    /* Build the form error dialog ready to be shown if there is a form */
    if ($('form').length > 0)
    {
        FormError.init();
    }
    
    /* Attach the ValidateForm function to submit buttons if they are not confirm buttons */
    $('input[type="submit"]').each(function()
    {
        if (!$(this).hasClass('confirm'))
        {
            $(this).click(ValidateForm);
        }
    });
});
/*
- - ( FILE INFO ) - - - - - - - - - - - - - - - - - - - - - - - - 
 Name:           protomatter.global.js
 Title:          General scripts run on all pages
 Author:         Colin Mc Mahon [Protomatter Web Solutions]
                 www.protomatter.co.uk
 Version:        1.0
 Updated:        20/06/2008
- - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - 
*/
/// <reference path="jquery-1.2.3-vsdoc.js" />

var utils = {
	goUrl : function(url)
	{
		if (url == 'back') {
			history.go(-1);
		} else {
			document.location = url;
		}
	},
	OpenWindow : function(in_url, in_win_id, in_width, in_height, in_scroll_bars) {
		if (in_width ==="" || in_width === null) { in_width = 486; }
		if (in_height === "" || in_height === null) { in_height = 500; }
		var features ='directories=0,location=0,menubar=0,scrollbars=' + in_scroll_bars + ',status=0,toolbar=0,resizable=1,width=' + in_width + ',height=' + in_height + ',screenX=15,screenY=15,top=15,left=15';
		in_url = in_url.replace(/\s/,'%20');
		var wind=window.open (in_url, in_win_id, features);
		wind.focus();
	},
	trim : function (str) {
		var	str = str.replace(/^\s\s*/, ''),
			ws = /\s/,
			i = str.length;
		while (ws.test(str.charAt(--i)));
		return str.slice(0, i + 1);
	},
	GetParam : function(name, str) {
		name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
		var regexS = "[\\?&]"+name+"=([^&#]*)";
		var regex = new RegExp( regexS );
		var results = regex.exec( str );
		if( results === null )
		{
			return "";
		}
		else
		{
			return results[1];
		}
	},
	GetQS : function(name) {
		return utils.GetParam(name, window.location.href);
	},
	setCookie : function(c_name,value,expiredays,path)
	{
		var exdate=new Date()
		exdate.setDate(exdate.getDate()+expiredays)
		document.cookie=c_name+ "=" +escape(value)+
		((expiredays==null) ? "" : ";expires="+exdate.toGMTString())+
		((path) ? "; path=" + path : "");
	},
	getCookie : function(c_name)
	{
		if (document.cookie.length>0)
		{
			c_start=document.cookie.indexOf(c_name + "=")
			if (c_start!=-1)
			{ 
				c_start=c_start + c_name.length+1 
				c_end=document.cookie.indexOf(";",c_start)
				if (c_end==-1) c_end=document.cookie.length
				return unescape(document.cookie.substring(c_start,c_end))
			} 
		}
		return ""
	}
};

jQuery.preloadImages = function()
{
    for(var i = 0; i<arguments.length; i++)
    {
        jQuery("<img>").attr("src", arguments[i]);
    }
};

SetSavedMessage = function(msg)
{
	$('#system-message').remove();
	$(document.body).append(
		$("<div id=\"system-message\" class=\"positive\">" + msg + "</div>").oneTime(6000, function() {
			$(this).fadeOut();
		})
	);
};

SetAjaxMessage = function(msg)
{
	$('#system-message').remove();
	$(document.body).append("<div id=\"system-message\" class=\"loading\">" + msg + "</div>");
}

SetReloadSavedMessage = function(msg)
{
	utils.setCookie("msg", msg, 200, "/");
};

GenPass = {
	init : function(in_field)
	{
		$('#generate-password').click(function(){
		    $.get('/admin/admin-ajax.ashx?action=GenPass', function(data)
		    {
		        $('#' + in_field).val(data);
		    });
		});
	}
};

/*
--------------------------------------------------
Initialise the above
--------------------------------------------------
*/
$(function()
{
    $(".back").click(function(e){
		e.preventDefault();
		utils.goUrl("back");
    });
	
	$("#system-message").oneTime(10000, function() {
		$(this).fadeOut();
    });
	
	$("select.pg-jump").change(function(){
		var url = window.location.pathname + $.query.set("pg", $(this).val()).toString();
		utils.goUrl(url);
    });
	
	$('a.help[rel]').each(function(){
		$(this).qtip({
			content: {
				text: '<img class="throbber" src="/admin/core/assets/images/working.gif" alt="Loading..." />',
				url: $(this).attr('rel'),
				method: 'get'
			},
			show: { 
				when: 'click', 
				solo: true // Only show one tooltip at a time
			},
			hide: 'unfocus',
			style: {
				tip: true, // Apply a speech bubble tip to the tooltip at the designated tooltip corner
				border: {
				width: 0,
				radius: 4
			},
			name: 'light', // Use the default light style
			width: 570 // Set the tooltip width
			}
		}).click(function(e){
			e.preventDefault();
		});
    });
	if(jQuery.datepicker) {
		$('.date').datepicker({showOn: 'button', buttonImage: '/assets/images/calendar.png', buttonImageOnly: true, dateFormat: 'dd/mm/yy'});
	}
});



