/*
 * Tooltip - jQuery plugin  for styled tooltips
 *
 * Copyright (c) 2006 Jörn Zaefferer, Stefan Petre
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id$
 *
 */

/**
 * Display a customized tooltip instead of the default one
 * for every selected element. The tooltip behaviour mimics
 * the default one, but lets you style the tooltip and
 * specify the delay before displaying it.
 *
 * In addition, it displays the href value, if it is available.
 * 
 * To style the tooltip, use these selectors in your stylesheet:
 *
 * #tooltip - The tooltip container
 *
 * #tooltip h3 - The tooltip title
 *
 * #tooltip p.body - The tooltip body, shown when using showBody
 *
 * #tooltip p.url - The tooltip url, shown when using showURL
 *
 * @example $('a, input, img').Tooltip();
 * @desc Shows tooltips for anchors, inputs and images, if they have a title
 *
 * @example $('label').Tooltip({
 *   delay: 0,
 *   track: true,
 *   event: "click"
 * });
 * @desc Shows tooltips for labels with no delay, tracking mousemovement, displaying the tooltip when the label is clicked.
 *
 * @example // modify global settings
 * $.extend($.fn.Tooltip.defaults, {
 * 	track: true,
 * 	delay: 0,
 * 	showURL: false,
 * 	showBody: " - ",
 *  fixPNG: true
 * });
 * // setup fancy tooltips
 * $('a.pretty').Tooltip({
 * 	 extraClass: "fancy"
 * });
 $('img.pretty').Tooltip({
 * 	 extraClass: "fancy-img",
 * });
 * @desc This example starts with modifying the global settings, applying them to all following Tooltips; Afterwards, Tooltips for anchors with class pretty are created with an extra class for the Tooltip: "fancy" for anchors, "fancy-img" for images
 *
 * @param Object settings (optional) Customize your Tooltips
 * @option Number delay The number of milliseconds before a tooltip is display, default is 250
 * @option String event The event on which the tooltip is displayed, default is "mouseover", "click" works fine, too
 * @option Boolean track If true, let the tooltip track the mousemovement, default is false
 * @option Boolean showURL If true, shows the href or src attribute within p.url, default is true
 * @option String showBody If specified, uses the String to split the title, displaying the first part in the h3 tag, all following in the p.body tag, separated with <br/>s, default is null
 * @option String extraClass If specified, adds the class to the tooltip helper, default is null
 * @option Boolean fixPNG If true, fixes transparent PNGs in IE, default is false
 *
 * @name Tooltip
 * @type jQuery
 * @cat Plugins/Tooltip
 * @author Jörn Zaefferer (http://bassistance.de)
 */
(function($) {
	
	// the tooltip element
	var helper,
		// it's title part
		tTitle,
		// it's body part
		tBody,
		// it's url part
		tUrl,
		// the current tooltipped element
		current,
		// the title of the current element, used for restoring
		oldTitle,
		// timeout id for delayed tooltips
		tID;
	
	// the public plugin method
	$.fn.Tooltip = function(settings) {
		// setup configuration
		settings = $.extend({}, arguments.callee.defaults, settings);
	
		// there can be only one tooltip helper
		if( !helper ) {
			// create the helper, h3 for title, div for url
			helper = $('<div id="tooltip"><h3></h3><p class="body"></p><p class="url"></p></div>')
				// hide it at first
				.hide()
				// move to top and position absolute, to let it follow the mouse
				.css({ position: 'absolute', zIndex: "3000" })
				// add to document
				.appendTo('body');
			
			// save references to title and url elements
			tTitle = $('h3', helper);
			tBody = $('p.body', helper);
			tUrl = $('p.url', helper);
		}
		
		// bind events for every selected element with a title attribute
		$(this).filter('[@title]')
			// save settings into each element
			.each(function() {
				this.tSettings = settings;
			})
			// bind events
			.bind("mouseover", save)
			.bind(settings.event, handle);
		return this;
	};
	
	// main event handler to start showing tooltips
	function handle(event) {
		// show helper, either with timeout or on instant
		if( this.tSettings.delay )
			tID = setTimeout(show, this.tSettings.delay);
		else
			show();
		
		// if selected, update the helper position when the mouse moves
		if(this.tSettings.track)
			$('body').bind('mousemove', update);
			
		// update at least once
		update(event);
		
		// hide the helper when the mouse moves out of the element
		$(this).bind('mouseout', hide);
	}
	
	// save elements title before the tooltip is displayed
	function save() {
		// if this is the current source, or it has no title (occurs with click event), stop
		if(this == current || !this.title)
			return;
		// save current
		current = this;
		
		var source = $(this),
			settings = this.tSettings;
			
		// save title, remove from element and set to helper
		var title = oldTitle = source.attr('title');
		source.attr('title','');
		if(settings.showBody) {
			var parts = title.split(settings.showBody);
			tTitle.html(parts.shift());
			tBody.empty();
			for(var i = 0, part; part = parts[i]; i++) {
				if(i > 0)
					tBody.append("<br/>");
				tBody.append(part);
			}
			if(tBody.html())
				tBody.show();
			else
				tBody.hide();
		} else {
			tTitle.html(title);
			tBody.hide();
		}
		
		// if element has href or src, add and show it, otherwise hide it
		var href = (source.attr('href') || source.attr('src'));
		if( settings.showURL && href )
			tUrl.html(href.replace('http://', '')).show();
		else 
			tUrl.hide();
		
		// add an optional class for this tip
		if( settings.extraClass ) {
			helper.addClass(settings.extraClass);
		}
		// fix PNG background for IE
		if (settings.fixPNG && $.browser.msie ) {
			helper.each(function () {
				if (this.currentStyle.backgroundImage != 'none') {
					var image = this.currentStyle.backgroundImage;
					image = image.substring(5, image.length - 2);
					$(this).css({
						'backgroundImage': 'none',
						'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
					});
				}
			});
		}
	}
	
	// delete timeout and show helper
	function show() {
		tID = null;
		helper.show();
		update();
	}
	
	/**
	 * callback for mousemove
	 * updates the helper position
	 * removes itself when no current element
	 */
	function update(event)	{
		// if no current element is available, remove this listener
		if( current == null ) {
			$('body').unbind('mousemove', update);
			return;	
		}
		
		var left = helper[0].offsetLeft;
		var top = helper[0].offsetTop;
		if(event) {
			// position the helper 15 pixel to bottom right, starting from mouse position
			left = event.pageX + 15;
			top = event.pageY + 15;
			helper.css({
				left: left + 'px',
				top: top + 'px'
			});
		}
		
		var v = viewport(),
			h = helper[0];
		// check horizontal position
		if(v.x + v.cx < h.offsetLeft + h.offsetWidth) {
			left -= h.offsetWidth + 20;
			helper.css({left: left + 'px'});
		}
		// check vertical position
		if(v.y + v.cy < h.offsetTop + h.offsetHeight) {
			top -= h.offsetHeight + 20;
			helper.css({top: top + 'px'});
		}
	}
	
	function viewport() {
		var e = document.documentElement || {},
			b = document.body || {},
			w = window;
		function min() {
			var v = Infinity;
			for( var i = 0;  i < arguments.length;  i++ ) {
				var n = arguments[i];
				if( n && n < v ) v = n;
			}
			return v;
		}
		return {
			x: w.pageXOffset || e.scrollLeft || b.scrollLeft || 0,
			y: w.pageYOffset || e.scrollTop || b.scrollTop || 0,
			cx: min( e.clientWidth, b.clientWidth, w.innerWidth ),
			cy: min( e.clientHeight, b.clientHeight, w.innerHeight )
		};
	}
	
	// hide helper and restore added classes and the title
	function hide() {
		// clear timeout if possible
		if(tID)
			clearTimeout(tID);
		// no more current element
		current = null;
		helper.hide();
		// remove optional class
		if( this.tSettings.extraClass ) {
			helper.removeClass( this.tSettings.extraClass);
		}
		
		// restore title and remove this listener
		$(this)
			.attr('title', oldTitle)
			.unbind('mouseout', hide);
			
		// remove PNG background fix for IE
		if( this.tSettings.fixPNG && $.browser.msie ) {
			helper.each(function () {
				$(this).css({'filter': '', backgroundImage: ''});
			});
		}
	}
	
	// define global defaults, editable by client
	$.fn.Tooltip.defaults = {
		delay: 250,
		event: "mouseover",
		track: false,
		showURL: true,
		showBody: null,
		extraClass: null,
		fixPNG: false
	};

})(jQuery);

(function($) {
					
$.fn.statBar = function() {

	$(this).each(function(){
		var timer = function(ul) {
			if (ul.$pause || $('> li', ul).size() == 1 ) {
				return;
			}
			var li 	= $('> li:first-child', ul)[0];
			var h	= $(li).outerHeight() + 1;
			var i 	= 0;
			ul.$animate = setInterval(function() {
				if (ul.$pause || $('> li', ul).size() == 1) {
					return;
				}
				if ((h + i) == 0) {
					clearInterval(ul.$animate);
					$('> li:last-child', ul).after(li);
					ul.style.top = '0px';
				} else {
					ul.style.top = (i--) + 'px';
				}
			}, 75);
		};

		$(this).hover(function() {
				$('> ul', this)[0].$pause = true;
			}, function() {
				var ul = $('> ul', this)[0];
				ul.$pause = false;
				clearInterval(ul.$interval);
				ul.$interval = setInterval(function(){ timer(ul); }, 4500);
			});

		var ul = $('> ul', this)[0];

		ul.$top = 0;
		ul.$interval = setInterval(function(){ timer(ul); }, 4500);
	});
}
$.fn.statBarClear = function(id) {
	if (id) {
		$('> ul > li', this).remove("#"+id);
		$('> ul', this).css("top","0px");
	} else {
		$('> ul', this).empty();
		$('> ul', this).get(0).innerHTML = '<li></li>';
		$('> ul', this).css("top","0px");
	}
}
$.fn.statBarAlert = function(newstat, id) {
	if ($('ul > li:first', this).get(0).innerHTML == "") {
		$('ul > li:first', this).get(0).innerHTML = newstat;
		if (id) { $('ul > li:first',this).attr("id",id); }	
		$('ul > li:first',this).css({color: "red", 'text-decoration': "blink"});
} else {
		if (id) {
			$('<li id="' + id + '" style="color: red; text-decoration: blink;">' + newstat + '</li>').insertBefore('ul > li:first-child',this);
		} else {
			$('<li style="color: red; text-decoration: blink;">' + newstat + '</li>').insertBefore('ul > li:first-child',this);
		}
	}
	var ul = $('> ul', this)[1];

	ul.$top = 0;
	clearInterval(ul.$interval);
	clearInterval(ul.$animate);
//	ul.$interval = setInterval(function(){ timer(ul); }, 7000);
}
$.fn.statBarAdd = function(newstat, id) {
	if ($('ul > li:first', this).get(0).innerHTML == "") {
		$('ul > li:first', this).get(0).innerHTML = newstat;
		if (id) { $('ul > li:first',this).attr("id",id); }	
	} else {
		if (id) {
			$('<li id="' + id + '">' + newstat + '</li>').insertAfter('ul > li:first-child',this);
		} else {
			$('<li>' + newstat + '</li>').insertAfter('ul > li:first-child',this);
		}
	}
}
$.fn.statBarAddLast = function(newstat, id) {
if ($('ul > li:first', this).get(0).innerHTML == "") {
		$('ul > li:first', this).get(0).innerHTML = newstat;
		if (id) { $('ul > li:first',this).attr("id",id); }	
	} else { 
		if (id) {
			$('<li id="' + id + '">' + newstat + '</li>').insertAfter('ul > li:last-child',this);
		} else {
			$('<li>' + newstat + '</li>').insertAfter('ul > li:last-child',this);
		}
	}
}


})(jQuery);
jQuery.fn.setlcol = function(content, notround) {
	if (content) {
		jQuery("div#mainlcol").get(0).innerHTML = ''; 
		jQuery("div#mainlcol").get(0).innerHTML = content; 
	} else {
		if (jQuery("div#mainlcol").get(0).innerHTML == '') {
			jQuery("div#mainlcol").get(0).innerHTML = '<!-- -->';
		}
	} 
	if	(jQuery("div#mainlcol").get(0).offsetHeight > 0 && jQuery("div#mainlcol > img.lcolround").size() == 0 && notround != 1) {
			jQuery("div#mainlcol").prepend('<img class="lcolround" src=\"/admin/images/lcol_01.png\" style="visibility=visible;">');
			jQuery("div#mainlcol").append('<img class="lcolround" src=\"/admin/images/lcol_03.png\" style="visibility=visible;">');
	}
};
/*
 * Date picker plugin for jQuery
 * http://kelvinluck.com/assets/jquery/datePicker
 *
 * Copyright (c) 2006 Kelvin Luck (kelvnluck.com)
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * $LastChangedDate: 2007-02-13 11:32:41 +0000 (Tue, 13 Feb 2007) $
 * $Rev: 1334 $
 */

jQuery.datePicker = function()
{
	// so that firebug console.log statements don't break IE
	if (window.console == undefined) { window.console = {log:function(){}}; }

	var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
	var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
	var navLinks = {p:'Prev', n:'Next', c:'Close', b:'Choose date'};
	var dateFormat = 'dmy';
	var dateSeparator = "/";
	var _drawingMonth = false;
	var _firstDayOfWeek;
	var _firstDate;
	var _lastDate;

	var _selectedDate;
	var _openCal;

	var _zeroPad = function(num) {
		var s = '0'+num;
		return s.substring(s.length-2)
		//return ('0'+num).substring(-2); // doesn't work on IE :(
	};
	var _strToDate = function(dIn)
	{
		switch (dateFormat) {
			case 'ymd':
				dParts = dIn.split(dateSeparator);
				return new Date(dParts[0], Number(dParts[1])-1, dParts[2]);
			case 'dmy':
				dParts = dIn.split(dateSeparator);
				return new Date(dParts[2], Number(dParts[1])-1, Number(dParts[0]));
			case 'dmmy':
				dParts = dIn.split(dateSeparator);
				for (var m=0; m<12; m++) {
					if (dParts[1].toLowerCase() == months[m].substr(0,3).toLowerCase())  {
						return new Date(Number(dParts[2]), m, Number(dParts[0]));
					}
				}
				return undefined;
			case 'mdy':
			default:
				var parts = parts ? parts : [2, 1, 0];
				dParts = dIn.split(dateSeparator);
				return new Date(dParts[2], Number(dParts[0])-1, Number(dParts[1]));
		}
	};
	var _dateToStr = function(d)
	{
		var dY = d.getFullYear();
		var dM = _zeroPad(d.getMonth()+1);
		var dD = _zeroPad(d.getDate());
		switch (dateFormat) {
			case 'ymd':
				return dY + dateSeparator + dM + dateSeparator + dD;
			case 'dmy':
				return dD + dateSeparator + dM + dateSeparator + dY;
			case 'dmmy':
				return dD + dateSeparator + months[d.getMonth()].substr(0,3) + dateSeparator + dY;
			case 'mdy':
			default:
				return dM + dateSeparator + dD + dateSeparator + dY;
		}
	};

	var _getCalendarDiv = function(dIn)
	{
		var today = new Date();
		if (dIn == undefined) {
			// start from this month.
			d = new Date(today.getFullYear(), today.getMonth(), 1);
		} else {
			// start from the passed in date
			d = dIn;
			d.setDate(1);
		}
		// check that date is within allowed limits:
		if ((d.getMonth() < _firstDate.getMonth() && d.getFullYear() == _firstDate.getFullYear()) || d.getFullYear() < _firstDate.getFullYear()) {
			d = new Date(_firstDate.getFullYear(), _firstDate.getMonth(), 1);;
		} else if ((d.getMonth() > _lastDate.getMonth() && d.getFullYear() == _lastDate.getFullYear()) || d.getFullYear() > _lastDate.getFullYear()) {
			d = new Date(_lastDate.getFullYear(), _lastDate.getMonth(), 1);;
		}

		var jCalDiv = jQuery("<div>").attr('class','popup-calendar');
		var firstMonth = true;
		var firstDate = _firstDate.getDate();

		// create prev and next links
		var prevLinkDiv = '';
		if (!(d.getMonth() == _firstDate.getMonth() && d.getFullYear() == _firstDate.getFullYear())) {
			// not in first display month so show a previous link
			firstMonth = false;
			var lastMonth = d.getMonth() == 0 ? new Date(d.getFullYear()-1, 11, 1) : new Date(d.getFullYear(), d.getMonth()-1, 1);
			var prevLink = jQuery("<a>").attr('href', 'javascript:;').html(navLinks.p).click(function()
			{
				jQuery.datePicker.changeMonth(lastMonth, this);
				return false;
			});
			prevLinkDiv = jQuery("<div>").attr('class','link-prev').html('&lt;').append(prevLink);
		}

		var finalMonth = true;
		var lastDate = _lastDate.getDate();
		nextLinkDiv = '';
		if (!(d.getMonth() == _lastDate.getMonth() && d.getFullYear() == _lastDate.getFullYear())) {
			// in the last month - no next link
			finalMonth = false;
			var nextMonth = new Date(d.getFullYear(), d.getMonth()+1, 1);
			var nextLink = jQuery("<a>").attr('href', 'javascript:;').html(navLinks.n).click(function()
			{
				jQuery.datePicker.changeMonth(nextMonth, this);
				return false;
			});
			nextLinkDiv = jQuery("<div>").attr('class','link-next').html('&gt;').prepend(nextLink);
		}

		var closeLink = jQuery("<a>").attr('href','javascript:;').html(navLinks.c).click(function()
		{
			jQuery.datePicker.closeCalendar();
		});

		jCalDiv.append(
			jQuery("<div>").attr('class', 'link-close').append(closeLink),
			jQuery("<h3>").html(months[d.getMonth()] + ' ' + d.getFullYear())
		);
		var headRow = jQuery("<tr>");
		for (var i=_firstDayOfWeek; i<_firstDayOfWeek+7; i++) {
			var weekday = i%7;
			var day = days[weekday];
			headRow.append(
				jQuery("<th>").attr({'scope':'col', 'abbr':day, 'title':day, 'class':(weekday == 0 || weekday == 6 ? 'weekend' : 'weekday')}).html(day.substr(0, 1))
			);
		}

		var tBody = jQuery("<tbody>");

		var lastDay = (new Date(d.getFullYear(), d.getMonth()+1, 0)).getDate();
		var curDay = _firstDayOfWeek - d.getDay();
		if (curDay > 0) curDay -= 7;

		var todayDate = (new Date()).getDate();
		var thisMonth = d.getMonth() == today.getMonth() && d.getFullYear() == today.getFullYear();

		var w = 0;
		while (w++<6) {
			var thisRow = jQuery("<tr>");
			for (var i=0; i<7; i++) {
				var weekday = (_firstDayOfWeek + i) % 7;
				var atts = {'class':(weekday == 0 || weekday == 6 ? 'weekend ' : 'weekday ')};

				if (curDay < 0 || curDay >= lastDay) {
					dayStr = ' ';
				} else if (firstMonth && curDay < firstDate-1) {
					dayStr = curDay+1;
					atts['class'] += 'inactive';
				} else if (finalMonth && curDay > lastDate-1) {
					dayStr = curDay+1;
					atts['class'] += 'inactive';
				} else {
					d.setDate(curDay+1);
					var dStr = _dateToStr(d);
					dayStr = jQuery("<a>").attr({'href':'javascript:;', 'rel':dStr}).html(curDay+1).click(function(e)
					{
						jQuery.datePicker.selectDate(jQuery.attr(this, 'rel'), this);
						return false;
					})[0];
					if (_selectedDate && _selectedDate==dStr) {
						jQuery(dayStr).attr('class','selected');
					}
				}

				if (thisMonth && curDay+1 == todayDate) {
					atts['class'] += 'today';
				}
				thisRow.append(jQuery("<td>").attr(atts).append(dayStr));
				curDay++;
			}
			tBody.append(thisRow);
		}

		jCalDiv.append(
			jQuery("<table>").attr('cellspacing',2).attr('id','calendar-table').append("<thead>")
			.find("thead").append(headRow).parent().append(tBody.children())
		).append(prevLinkDiv).append(nextLinkDiv);

		if (jQuery.browser.msie) {

			// we put a styled iframe behind the calendar so HTML SELECT elements don't show through
			var iframe = [	'<iframe class="bgiframe" tabindex="-1" ',
		 					'style="display:block; position:absolute;',
							'top: 0;',
							'left:0;',
							'z-index:-1; filter:Alpha(Opacity=\'0\');',
							'width:3000px;',
							'height:3000px"/>'].join('');
			jCalDiv.append(document.createElement(iframe));
		}
		jCalDiv.css({'display':'block'});
		return jCalDiv[0];
	};
	var _draw = function(c)
	{
		// explicitly empty the calendar before removing it to reduce the (MASSIVE!) memory leak in IE
		// still not perfect but a lot better!
		// Strangely if you chain the methods it reacts differently - when chained opening the calendar on
		// IE uses a bunch of memory and pressing next/prev doubles this memory. When you close the calendar
		// the memory is freed. If they aren't chained then pressing next or previous doesn't double the used
		// memory so only one chunk of memory is used when you open the calendar (which is also freed when you
		// close the calendar).
		jQuery('div.popup-calendar a', _openCal[0]).unbind();
		jQuery('div.popup-calendar', _openCal[0]).empty();
		jQuery('div.popup-calendar', _openCal[0]).remove();
		_openCal.append(c);
	};
	var _closeDatePicker = function()
	{
		jQuery('div.popup-calendar a', _openCal).unbind();
		jQuery('div.popup-calendar', _openCal).empty();
		jQuery('div.popup-calendar', _openCal).css({'display':'none'});

		/*
		if (jQuery.browser.msie) {
			_openCal.unbind('keypress', _handleKeys);
		} else {
			jQuery(window).unbind('keypress', _handleKeys);
		}
		*/
		jQuery(document).unbind('mousedown', _checkMouse);
		delete _openCal;
		_openCal = null;
	};
	var _handleKeys = function(e)
	{
		var key = e.keyCode ? e.keyCode : (e.which ? e.which: 0);
		//console.log('KEY!! ' + key);
		if (key == 27) {
			_closeDatePicker();
		}
		return false;
	};
	var _checkMouse = function(e)
	{
		if (!_drawingMonth) {
			var target = jQuery.browser.msie ? window.event.srcElement : e.target;
			var cp = jQuery(target).findClosestParent('div.popup-calendar');
			if (cp.get(0).className != 'date-picker-holder') {
				_closeDatePicker();
			}
		}
	};

	return {
		getChooseDateStr: function()
		{
			return navLinks.b;
		},
		show: function()
		{
			if (_openCal) {
				_closeDatePicker();
			}
			this.blur();
				var input = jQuery('input', jQuery(this).findClosestParent('input')[0])[0];
			_firstDate = input._startDate;
			_lastDate = input._endDate;
			_firstDayOfWeek = input._firstDayOfWeek;
			_openCal = jQuery(this).findClosestParent('div.popup-calendar');
			
			var d = jQuery(input).val();
			if (d != '') {
				if (_dateToStr(_strToDate(d)) == d) {
					_selectedDate = d;
					_draw(_getCalendarDiv(_strToDate(d)));
				} else {
					// invalid date in the input field - just default to this month
					_selectedDate = false;
					_draw(_getCalendarDiv());
				}
			} else {
				_selectedDate = false;
				_draw(_getCalendarDiv());
			}
			/*
			if (jQuery.browser == "msie") {
				_openCal.bind('keypress', _handleKeys);
			} else {
				jQuery(window).bind('keypress', _handleKeys);
			}
			*/
			jQuery(document).bind('mousedown', _checkMouse);
		},
		changeMonth: function(d, e)
		{
			_drawingMonth = true;
			_draw(_getCalendarDiv(d));
			_drawingMonth = false;
		},
		selectDate: function(d, ele)
		{
			selectedDate = d;
			var $theInput = jQuery('input', jQuery(ele).findClosestParent('input')[0]);
			$theInput.val(d);
			$theInput.trigger('change');
			_closeDatePicker(ele);
		},
		closeCalendar: function()
		{
			_closeDatePicker(this);
		},
		setInited: function(i)
		{
			i._inited = true;
		},
		isInited: function(i)
		{
			return i._inited != undefined;
		},
		setDateFormat: function(format,separator)
		{
			// set's the format that selected dates are returned in.
			// options are 'dmy' (european), 'mdy' (americian) and 'ymd' (unicode)
			dateFormat = format.toLowerCase();
			dateSeparator = separator?separator:"/";
		},
		/**
		* Function: setLanguageStrings
		*
		* Allows you to localise the calendar by passing in relevant text for the english strings in the plugin.
		*
		* Arguments:
		* days		-	Array, e.g. ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
		* months	-	Array, e.g. ['January', 'Febuary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
		* navLinks	-	Object, e.g. {p:'Prev', n:'Next', c:'Close', b:'Choose date'}
		**/
		setLanguageStrings: function(aDays, aMonths, aNavLinks)
		{
			days = aDays;
			months = aMonths;
			navLinks = aNavLinks;
		},
		/**
		* Function: setDateWindow
		*
		* Used internally to set the start and end dates for a given date select
		*
		* Arguments:
		* i			-	The id of the INPUT element this date window is for
		* w			-	The date window - an object containing startDate and endDate properties
		*				each in the current format as set in a call to setDateFormat (or in the
		*				default format dmy if setDateFormat hasn't been called).
		*				e.g. {startDate:'01/03/2006', endDate:'11/04/2006}
		**/
		setDateWindow: function(i, w)
		{
			if (w == undefined) w = {};
			if (w.startDate == undefined) {
				i._startDate = new Date();
			} else {
				i._startDate = _strToDate(w.startDate);
			}
			if (w.endDate == undefined) {
				i._endDate = new Date();
				i._endDate.setFullYear(i._endDate.getFullYear()+5);
			} else {
				i._endDate = _strToDate(w.endDate);
			};
			i._firstDayOfWeek = w.firstDayOfWeek == undefined ? 0 : w.firstDayOfWeek;
		}
	};
}();
jQuery.fn.findClosestParent = function(s)
{
	var ele = this;
	while (true) {
		if (jQuery(s, ele[0]).length > 0) {
			return (ele);
		}
		ele = ele.parent();
		if(ele[0].length == 0) {
			return false;
		}
	}
};
jQuery.fn.datePicker = function(a)
{
	this.each(function() {
		if(this.nodeName.toLowerCase() != 'input') return;
		jQuery.datePicker.setDateWindow(this, a);
		if (!jQuery.datePicker.isInited(this)) {
			var chooseDate = jQuery.datePicker.getChooseDateStr();
			var calBut;
			if(a && a.inputClick){
				calBut = jQuery(this).attr('title', chooseDate).addClass('date-picker');
			}
			else {
				calBut = jQuery("<a>").attr({'href':'javascript:;',
'class':'date-picker', 'title':chooseDate})
				.append("<span>" + chooseDate + "</span>");
			}
			jQuery(this).wrap(
				'<div class="date-picker-holder"></div>'
			).before(
				jQuery("<div>").attr({'class':'popup-calendar'})
			).after(
				calBut
			);
			calBut.bind('click', jQuery.datePicker.show);
			jQuery.datePicker.setInited(this);
		}
	});
	return this;
};
/*
<!-- Generated calendar HTML looks like this - style with CSS -->
<div class="popup-calendar">
	<div class="link-close"><a href="#">Close</a></div>
	<h3>July 2006</h3>
	<table cellspacing="2">
		<thead>
			<tr>
				<th scope="col" abbr="Monday" title="Monday" class="weekday">M</th>
				<th scope="col" abbr="Tuesday" title="Tuesday" class="weekday">T</th>
				<th scope="col" abbr="Wednesday" title="Wednesday" class="weekday">W</th>
				<th scope="col" abbr="Thursday" title="Thursday" class="weekday">T</th>
				<th scope="col" abbr="Friday" title="Friday" class="weekday">F</th>
				<th scope="col" abbr="Saturday" title="Saturday" class="weekday">S</th>
				<th scope="col" abbr="Sunday" title="Sunday" class="weekday">S</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td class="weekday">&nbsp;</td>
				<td class="weekday">&nbsp;</td>
				<td class="weekday">&nbsp;</td>
				<td class="inactive weekday">1</td>
				<td class="inactive weekday">2</td>
				<td class="inactive weekend">3</td>
				<td class="inactive weekend">4</td>
			</tr>
			<tr>
				<td class="inactive weekday">5</td>
				<td class="inactive weekday">6</td>
				<td class="inactive weekday">7</td>
				<td class="today weekday"><a href="#">8</a></td>
				<td class="weekday"><a href="#">9</a></td>
				<td class="weekend"><a href="#">10</a></td>
				<td class="weekend"><a href="#">11</a></td>
			</tr>
			<tr>
				<td class="weekday"><a href="#">12</a></td>
				<td class="weekday"><a href="#">13</a></td>
				<td class="weekday"><a href="#">14</a></td>
				<td class="weekday"><a href="#">15</a></td>
				<td class="weekday"><a href="#">16</a></td>
				<td class="weekend"><a href="#">17</a></td>
				<td class="weekend"><a href="#" class="selected">18</a></td>
			</tr>
			<tr>
				<td class="weekday"><a href="#">19</a></td>
				<td class="weekday"><a href="#">20</a></td>
				<td class="weekday"><a href="#">21</a></td>
				<td class="weekday"><a href="#">22</a></td>
				<td class="weekday"><a href="#">23</a></td>
				<td class="weekend"><a href="#">24</a></td>
				<td class="weekend"><a href="#">25</a></td>
			</tr>
			<tr>
				<td class="weekday"><a href="#">26</a></td>
				<td class="weekday"><a href="#">27</a></td>
				<td class="weekday"><a href="#">28</a></td>
				<td class="weekday"><a href="#">29</a></td>
				<td class="weekday"><a href="#">30</a></td>
				<td class="weekend">&nbsp;</td>
				<td class="weekend">&nbsp;</td>
			</tr>
		</tbody>
	</table>
	<div class="link-prev"><a href="#">Prev</a></div>
	<div class="link-next"><a href="#">Next</a></div>
</div>
*/
/*
 * jQuery corner plugin
 *
 * version 1.7 (1/26/2007)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

/**
 * The corner() method provides a simple way of styling DOM elements.  
 *
 * corner() takes a single string argument:  $().corner("effect corners width")
 *
 *   effect:  The name of the effect to apply, such as round or bevel. 
 *            If you don't specify an effect, rounding is used.
 *
 *   corners: The corners can be one or more of top, bottom, tr, tl, br, or bl. 
 *            By default, all four corners are adorned. 
 *
 *   width:   The width specifies the width of the effect; in the case of rounded corners this 
 *            will be the radius of the width. 
 *            Specify this value using the px suffix such as 10px, and yes it must be pixels.
 *
 * For more details see: http://methvin.com/jquery/jq-corner.html
 * For a full demo see:  http://malsup.com/jquery/corner/
 *
 *
 * @example $('.adorn').corner();
 * @desc Create round, 10px corners 
 *
 * @example $('.adorn').corner("25px");
 * @desc Create round, 25px corners 
 *
 * @example $('.adorn').corner("notch bottom");
 * @desc Create notched, 10px corners on bottom only
 *
 * @example $('.adorn').corner("tr dog 25px");
 * @desc Create dogeared, 25px corner on the top-right corner only
 *
 * @example $('.adorn').corner("round 8px").parent().css('padding', '4px').corner("round 10px");
 * @desc Create a rounded border effect by styling both the element and its parent
 * 
 * @name corner
 * @type jQuery
 * @param String options Options which control the corner style
 * @cat Plugins/Corner
 * @return jQuery
 * @author Dave Methvin (dave.methvin@gmail.com)
 * @author Mike Alsup (malsup@gmail.com)
 */
jQuery.fn.corner = function(o) {
    function hex2(s) {
        var s = parseInt(s).toString(16);
        return ( s.length < 2 ) ? '0'+s : s;
    };
    function gpc(node) {
        for ( ; node && node.nodeName.toLowerCase() != 'html'; node = node.parentNode  ) {
            var v = jQuery.css(node,'backgroundColor');
            if ( v.indexOf('rgb') >= 0 ) { 
                rgb = v.match(/\d+/g); 
                return '#'+ hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
            }
            if ( v && v != 'transparent' )
                return v;
        }
        return '#ffffff';
    };
    function getW(i) {
        switch(fx) {
        case 'round':  return Math.round(width*(1-Math.cos(Math.asin(i/width))));
        case 'cool':   return Math.round(width*(1+Math.cos(Math.asin(i/width))));
        case 'sharp':  return Math.round(width*(1-Math.cos(Math.acos(i/width))));
        case 'bite':   return Math.round(width*(Math.cos(Math.asin((width-i-1)/width))));
        case 'slide':  return Math.round(width*(Math.atan2(i,width/i)));
        case 'jut':    return Math.round(width*(Math.atan2(width,(width-i-1))));
        case 'curl':   return Math.round(width*(Math.atan(i)));
        case 'tear':   return Math.round(width*(Math.cos(i)));
        case 'wicked': return Math.round(width*(Math.tan(i)));
        case 'long':   return Math.round(width*(Math.sqrt(i)));
        case 'sculpt': return Math.round(width*(Math.log((width-i-1),width)));
        case 'dog':    return (i&1) ? (i+1) : width;
        case 'dog2':   return (i&2) ? (i+1) : width;
        case 'dog3':   return (i&3) ? (i+1) : width;
        case 'fray':   return (i%2)*width;
        case 'notch':  return width; 
        case 'bevel':  return i+1;
        }
    };
    o = (o||"").toLowerCase();
    var keep = /keep/.test(o);                       // keep borders?
    var cc = ((o.match(/cc:(#[0-9a-f]+)/)||[])[1]);  // corner color
    var sc = ((o.match(/sc:(#[0-9a-f]+)/)||[])[1]);  // strip color
    var width = parseInt((o.match(/(\d+)px/)||[])[1]) || 10; // corner width
    var re = /round|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dog/;

    var fx = ((o.match(re)||['round'])[0]);
    var edges = { T:0, B:1 };
    var opts = {
        TL:  /top|tl/.test(o),       TR:  /top|tr/.test(o),
        BL:  /bottom|bl/.test(o),    BR:  /bottom|br/.test(o)
    };
    if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
        opts = { TL:1, TR:1, BL:1, BR:1 };
    var strip = document.createElement('div');
    strip.style.overflow = 'hidden';
    strip.style.height = '1px';
    strip.style.backgroundColor = sc || 'transparent';
    strip.style.borderStyle = 'solid';
    return this.each(function(index){
        var pad = {
            T: parseInt(jQuery.css(this,'paddingTop'))||0,     R: parseInt(jQuery.css(this,'paddingRight'))||0,
            B: parseInt(jQuery.css(this,'paddingBottom'))||0,  L: parseInt(jQuery.css(this,'paddingLeft'))||0
        };

        if (jQuery.browser.msie) this.style.zoom = 1; // force 'hasLayout' in IE
        if (!keep) this.style.border = 'none';
        strip.style.borderColor = cc || gpc(this.parentNode);
        var cssHeight = jQuery.curCSS(this, 'height');

        for (var j in edges) {
            var bot = edges[j];
            strip.style.borderStyle = 'none '+(opts[j+'R']?'solid':'none')+' none '+(opts[j+'L']?'solid':'none');
            var d = document.createElement('div');
            var ds = d.style;

            bot ? this.appendChild(d) : this.insertBefore(d, this.firstChild);

            if (bot && cssHeight != 'auto') {
                if (jQuery.css(this,'position') == 'static')
                    this.style.position = 'relative';
                ds.position = 'absolute';
                ds.bottom = ds.left = ds.padding = ds.margin = '0';
                if (jQuery.browser.msie)
                    ds.setExpression('width', 'this.parentNode.offsetWidth');
                else
                    ds.width = '100%';
            }
            else {
                ds.margin = !bot ? '-'+pad.T+'px -'+pad.R+'px '+(pad.T-width)+'px -'+pad.L+'px' : 
                                    (pad.B-width)+'px -'+pad.R+'px -'+pad.B+'px -'+pad.L+'px';                
            }

            for (var i=0; i < width; i++) {
                var w = Math.max(0,getW(i));
                var e = strip.cloneNode(false);
                e.style.borderWidth = '0 '+(opts[j+'R']?w:0)+'px 0 '+(opts[j+'L']?w:0)+'px';
                bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
            }
        }
    });
};
