$(document).ready(function () {
/* start */

// carousel loga hotelu
var opts = { 
	align: 'middle',
  size: 50,
	distance: 60,
  coefficient : 1.5,
  labels: 'bc',
	duration: 500
  };

$('input[type=submit]').hover(function() { $(this).addClass('submitactive'); }, function() { $(this).removeClass('submitactive'); });

//$('#jqdock').jqDock(opts);

// kulate rohy u topmenu
$('.topMenu li a, .levyObsah .box, #weather span.popisek, .spodniBoxy .box, .submitbox').corner("notch 1px");
//$('.header .languages img').corner();

// promo slideshow
$('#promo').cycle({
	fx: 'fade',
	speed:    2000, 
	timeout:  4000 
});

// lightbox
$(".lightbox").lightbox();


// tabs
$("#tabs").tabs();

// dialog info
$('#dialog').dialog({
	autoOpen: false
});
$('#modcanres').click(function() {
	$('#dialog').dialog('open');
	return false;
});

// externi odkazy do noveho okna
$("a.external").attr('target', '_blank');


// prenastaveni formatu datumu pro pripadnou lokalizaci, abych umel desifrovat
if (getLang () != "en") {
	$.datepicker.regional[getLang ()] = {dateFormat:'mm/dd/yy'};
	$.datepicker.setDefaults($.datepicker.regional[getLang ()]);
}

/* --------------------------------------------------------------- */
// calendar
$('#calholder_arr').datepicker({
	numberOfMonths: 2,
	minDate: 0, 
	maxDate: '+1Y',
	showAnim: null,
	duration:0,
	firstDay: 1,
	onClose: function() { 
		$('#promo').toggleClass('novis');
		$('#tabs').toggleClass('novis');
	},
	onSelect: function(dateText, inst) {
		var date = new Date(dateText);
		var arrayM = new Array();
		arrayM = {1:"January",2:"February",3:"March",4:"April",5:"May",6:"June",7:"July",8:"August",9:"September",10:"October",11:"November",12:"December"};

		$("#arrival_day").val(date.getDate());
		$("#arrival_monthyear").val(""+arrayM[parseInt(date.getMonth()+1,10)]+" "+date.getFullYear());
		calChangeArr();
	}
});
$('#cal_arr').click(function() {
	$('#promo').toggleClass('novis');
	$('#tabs').toggleClass('novis');
	$('#calholder_arr').datepicker('show');
});

$('#calholder_dep').datepicker({
	numberOfMonths: 2,
	minDate: '+1D', 
	maxDate: '+1Y +1D',
	showAnim: null,
	duration:0,
	firstDay: 1,

	onClose: function() { 
		$('#promo').toggleClass('novis');
		$('#tabs').toggleClass('novis');
	},
	onSelect: function(dateText, inst) {
		var date = new Date(dateText);
		var arrayM = new Array();
		arrayM = {1:"January",2:"February",3:"March",4:"April",5:"May",6:"June",7:"July",8:"August",9:"September",10:"October",11:"November",12:"December"};

		$("#departure_day").val(date.getDate());
		$("#departure_monthyear").val(""+arrayM[parseInt(date.getMonth()+1,10)]+" "+date.getFullYear());
		calChangeDep();
	}
});
$('#cal_dep').click(function() {
	$('#promo').toggleClass('novis');
	$('#tabs').toggleClass('novis');	
	dates = parseDates();
	//$('#calholder_dep').datepicker( "setDate", '2010/05/10');
		dates[1].setTime(dates[0].getTime() + 86400000);
	$('#calholder_dep').datepicker("option", "minDate", dates[1]);
	$('#calholder_dep').datepicker('show');
});

// posun kalendare
$('#arrival_day, #arrival_monthyear').change(function() {
	calChangeArr();
});
$('#departure_day, #departure_monthyear').change(function() {
	calChangeDep();
});
function calChangeArr () {
	var montharray=new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	dates = parseDates();
	if (dates[0].getTime() >= dates[1].getTime())
		dates[1].setTime(dates[0].getTime() + 86400000);
	$('#departure_day').val(dates[1].getDate());
	$('#departure_monthyear').val(montharray[dates[1].getMonth()] + ' ' + dates[1].getFullYear());
}
function calChangeDep () {
	var montharray=new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	dates = parseDates();
	if (dates[1].getTime() <= dates[0].getTime())
		dates[0].setTime(dates[1].getTime() - 86400000);
	$('#arrival_day').val(dates[0].getDate());
	$('#arrival_monthyear').val(montharray[dates[0].getMonth()] + ' ' + dates[0].getFullYear());
}
function parseDates () {
	ad = $('#arrival_day').val();
	xa = $('#arrival_monthyear').val();
	xa = xa.split(' ');
	am = xa[0];
	ay = xa[1];
	adate = new Date(am+' '+ad+', '+ay);

	dd = $('#departure_day').val();
	xd = $('#departure_monthyear').val();
	xd = xd.split(' ');
	dm = xd[0];
	dy = xd[1];
	ddate = new Date(dm+' '+dd+', '+dy);

	return (Array(adate, ddate));
}

/* --------------------------------------------------------------- */

// otevirani a zavirani popisku
$('.priceopen').hover(function(event) {
	$(this).toggleClass('hover');
});
$('.priceopen').each(function(index) {
	$(this).click(function () {
		$('tr.'+$(this).attr("rel")).toggle();
		$('div.'+$(this).attr("rel")).toggle('blind');
		return false;
	});
});
$('.closetr').each(function(index) {
	$(this).click(function () {
		$('tr.'+$(this).attr("rel")).hide();
		$('div.'+$(this).attr("rel")).hide('blind');
		return false;
	});
});

// odeslani az po vybrani nejakeho pokoje + uprava ceny
// moznost zvolit benefity
roomchooseCheck();
$('#roomchoose .tp select').each(function() {
	$(this).change(function () {
		roomchooseCheck();
	});
});
function roomchooseCheck() {
	$('#roomchoose input[type=submit]').attr('disabled', 'disabled');
	$('#roomchoose .submitbox').removeClass('active');
	var total = 0;
	$('#roomchoose #totalprice span').html(total);
	$('#roomchoose .tp select').each(function() {
		tp = parseInt($(this).val());
		pokoj_id = $(this).attr('rel');			
		if (tp>0) {
			$('tr.pri_'+pokoj_id+':hidden').show();
			$('div.pri_'+pokoj_id+':hidden').show('blind');
			$('#roomchoose input[type=submit]').removeAttr('disabled');
			$('#roomchoose .submitbox').addClass('active');
			
			roomprice = tp*$('#roomchoose #tph_'+pokoj_id).html();
			total = total + roomprice;
			$('#roomchoose #totalprice span').html(total);
			//$('#roomchoose #tp_'+pokoj_id).html(tp*$('#roomchoose #tph_'+pokoj_id).html());

			// zapnu vyber benefitu a omezim pocet na aktualni pocet dle poctu pokoju a prictu k total price
			$('.pri_'+pokoj_id+'.benefit select').removeAttr('disabled');
			$('.pri_'+pokoj_id+'.benefit select').each(function () { 
				$(this).children().slice(0,tp+2).removeAttr('disabled'); 
				$(this).children().slice(tp+1).attr('disabled', 'disabled'); 

				tpb = parseInt($(this).val());
				if (tpb > tp)
					$(this).val(tp);
				benefitprice = tpb*$('.pri_'+pokoj_id+'.benefit #tpb_'+$(this).attr('rel')).html();
				total = total + benefitprice;
				//alert ('P '+benefitprice);
			});
		}
		else {
			// vypnu vyber benefitu
			$('.pri_'+pokoj_id+'.benefit select').val(0);
			$('.pri_'+pokoj_id+'.benefit select').attr('disabled', 'disabled');
		}
	});
}

/* --------------------------------------------------------------- */

// rezervace - transfer
$('#transferdata').hide();
/*
function transfer_show() {
	if ($('#ft_tyes').attr('checked'))
		$('#transferdata').show('blind');
	else
		$('#transferdata').hide('blind');
}
$("#ft_tyes, #ft_tno").change(transfer_show);
*/
$("#ft_location").change(function () {
	value = $(this).val();
	index = $(this).attr("selectedIndex");

	if (value) {
		$('#transferdata').show('blind');
		
		if (index == 1) {
			$('#f_car_lim_train_pms, #f_car_lim_train_hs, #f_car_van_train_pms, #f_car_van_train_hs').hide();
			$('#f_car_lim_air, #f_car_van_air').show();
		}
		else if (index == 2) {			
			$('#f_car_lim_air, #f_car_van_air, #f_car_lim_train_hs, #f_car_van_train_hs').hide();
			$('#f_car_lim_train_pms, #f_car_van_train_pms').show();	
		}
		else if (index == 3) {
			$('#f_car_lim_air, #f_car_van_air, #f_car_lim_train_pms, #f_car_van_train_pms').hide();		
			$('#f_car_lim_train_hs, #f_car_van_train_hs').show();
		}
	}
	else
		$('#transferdata').hide('blind');
});


// vyber casu
$("#ft_arrival").timePicker({
  step: 15});


// vyber casu
$("#c_arrival").timePicker({
  step: 15});

// formular - zvyraznine
$('.normalform .inputbox').hover(function(event) {
	$(this).toggleClass('hover');
});

// booking validace
$('form#booking .inputbox.required input, form#booking .inputbox.required select').bind('blur keyup change', function () {
	testValid (this);
});

$('form#booking').submit(function () {
	var form_error = false;
	form_ok = true;
	$('form#booking .inputbox.required input, form#booking .inputbox.required select').each (function () {
		tv = testValid(this);
		if(tv) {
			form_ok = false;
			form_error = tv;
		}
	});
	defvalid ($('form#booking .submitbox input[type=submit]'), form_ok);	
	if (!form_ok) {
		setTimeout ("$('form#booking .submitbox').removeClass('error').children('.err_msg').addClass('hide')",4000);
		
		var eburl = '/error-booking.php?';
		$('form#booking :input').each (function () {
			eburl = eburl + $(this).attr('name') + '=' + $(this).val() + '&';
		});
		eburl = eburl + 'failedon='+form_error;
		$.ajax({ url: eburl });
		//alert ('EB: '+eburl);
	}

	// ne 2x submit
	if (this.beenSubmitted || !form_ok)
		return false;
	else if (form_ok)
		this.beenSubmitted = true;
});

// vlastni kontrola formulare
function testValid(el) {
	validerror = false;
	// jmeno
	if ($(el).attr('name')=='jmeno') {
		if(!defvalid (el, $(el).val()))
				validerror = 'jmeno';
	}
	// email
	if ($(el).attr('name')=='email') {
		val = $(el).val();
		if(!defvalid (el, /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(val)))
			validerror = 'email';
	}
	// card_name
	if ($(el).attr('name')=='card_name') {
		if (!defvalid (el, $(el).val()))
			validerror = 'card name';
	}
	// Expiration Date (card_mesic+card_rok
	if ($(el).attr('name')=='card_mesic' || $(el).attr('name')=='card_rok') {
		val = new Date ();
		if (!defvalid (el, ($('#f_card_rok').val()+$('#f_card_mesic').val() > val.getFullYear()+(val.getMonth()<10 ? '0'+val.getMonth() : val.getMonth())) ? 1: 0))
			validerror = 'card expiration';
	}
	// Cislo karty (card_number + card_type)
	if ($(el).attr('name')=='card_type' || $(el).attr('name')=='card_num1' || $(el).attr('name')=='card_num2' || $(el).attr('name')=='card_num3' || $(el).attr('name')=='card_num4') {
		if ($('#f_card_type').val() == 'American Express')
			cislo = $('#f_card_num1').val()+$('#f_card_num2').val()+$('#f_card_num3').val();
		else
			cislo = $('#f_card_num1').val()+$('#f_card_num2').val()+$('#f_card_num3').val()+$('#f_card_num4').val();
		result = cc_check(cislo, $('#f_card_type').val());
		if (!defvalid ($('#f_card_type'), result))
			validerror = 'card number';
	}
	// souhlas
	if ($(el).attr('name')=='souhlas') {
		if(!defvalid (el, $(el).is(':checked')))
				validerror = 'aggreament';
	}
	return validerror;
}

// vysledek kontroly
function defvalid (el, result) {
	if (result) {
			$(el).parent().removeClass('error').addClass('ok');
			$(el).parent().children('.err_msg').addClass('hide');
		}
		else {
			//$(this).focus();
			$(el).parent().removeClass('ok').addClass('error');
			$(el).parent().children('.err_msg').removeClass('hide');
		}
	return result;
}

/* --------------------------------------------------------------- */

// transfer validace
$('form#conres .inputbox.required input, form#conres .inputbox.required select').bind('blur keyup change', function () {
	testValidTransfer (this);
});

$('form#conres').submit(function () {
	form_ok = true;
	$('form#conres .inputbox.required input, form#conres .inputbox.required select').each (function () {
		if(testValidTransfer(this))
			form_ok = false;
	});
	defvalid ($('form#conres .submitbox input[type=submit]'), form_ok);	
	if (!form_ok)
		setTimeout ("$('form#conres .submitbox').removeClass('error').children('.err_msg').addClass('hide')",4000);
	
	// ne 2x submit
	if (this.beenSubmitted || !form_ok)
		return false;
	else if (form_ok)
		this.beenSubmitted = true;
});

// vlastni kontrola formulare
function testValidTransfer(el) {
	validerror = false;
	// jmeno
	if ($(el).attr('name')=='jmeno') {
		if(!defvalid (el, $(el).val()))
				validerror = true;
	}
	// email
	if ($(el).attr('name')=='email') {
		val = $(el).val();
		if(!defvalid (el, /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(val)))
			validerror = true;
	}
	// termin
	if ($(el).attr('name')=='termin') {
		if (!defvalid (el, $(el).val()))
			validerror = true;
	}
	// arrival
	if ($(el).attr('name')=='arrival') {
		if (!defvalid (el, $(el).val()))
			validerror = true;
	}
	// flightnumber
	if ($(el).attr('name')=='flightnumber' && $('#f_ttype_airport').attr('checked')) {
		if (!defvalid (el, $(el).val()))
			validerror = true;
	}
	// trainnumber
	if ($(el).attr('name')=='trainnumber' && $('#f_ttype_train').attr('checked')) {
		if (!defvalid (el, $(el).val()))
			validerror = true;
	}
	// trainstation
	if ($(el).attr('name')=='trainstation' && $('#f_ttype_train').attr('checked')) {
		if (!defvalid (el, $(el).val()))
			validerror = true;
	}
	// departure
	if ($(el).attr('name')=='departure') {
		if (!defvalid (el, $(el).val()))
			validerror = true;
	}
	// kom_protirobotum
	if ($(el).attr('name')=='kom_protirobotum') {
		if (!defvalid (el, $(el).val()==4))
			validerror = true;
	}
	// souhlas
	if ($(el).attr('name')=='agree') {
		if(!defvalid (el, $(el).is(':checked')))
				validerror = true;
	}
	return validerror;
}

// prepinani formulare transferu
$('#f_ttype_airport, #f_ttype_train').change (function () {
	if ($('#f_ttype_airport').attr('checked')) {
		//$('#conres_form').hide('blind');
		$('#f_car_lim_train_pms, #f_car_lim_train_hs, #f_car_van_train_pms, #f_car_van_train_hs, #ib_c_trainstation, #ibc_c_trainnumber').hide();
		$('#f_car_lim_air, #f_car_van_air, #ibc_c_flightnumber').show();
		$('#conres_form').show('blind',null,1000);
	}
	else {	
		//$('#conres_form').hide('blind');
		$('#f_car_lim_air, #f_car_van_air, #ibc_c_flightnumber').hide();
		changeTrainPrice ();
		$('#ib_c_trainstation, #ibc_c_trainnumber').show();
		$('#conres_form').show('blind',null,1000);
	}
});

$('#c_trainstation').change (function () {changeTrainPrice ()});

function changeTrainPrice () {
	if ($('#f_ttype_train').attr('checked')) {
		//if ($('#c_trainstation').val()=='Holesovice station') {
		if ($('#c_trainstation option:nth-child(2)').is(':selected')) {
			$('#f_car_lim_train_pms, #f_car_van_train_pms').hide();		
			$('#f_car_lim_train_hs, #f_car_van_train_hs').show();
		}
		else {
			$('#f_car_lim_train_hs, #f_car_van_train_hs').hide();
			$('#f_car_lim_train_pms, #f_car_van_train_pms').show();		
		}
	}
}

$('#f_car_lim_train_pms, #f_car_lim_train_hs, #f_car_van_train_pms, #f_car_van_train_hs, #ib_c_trainstation, #ibc_c_trainnumber').hide();
$('#conres_form').hide();

// kalendar u tranferu
$('#c_termin').datepicker({
	numberOfMonths: 1,
	minDate: 0, 
	maxDate: '+1Y',
	showAnim: null,
	duration:0,
	dateFormat: 'd. m. yy',
	firstDay: 1
});
$('#cal_transfer').click(function() {
	$('#c_termin').datepicker('show');
});

/* --------------------------------------------------------------- */

// meeting room validace
$('form#meeting .inputbox.required input, form#meeting .inputbox.required select').bind('blur keyup change', function () {
	testValidMeeting (this);
});

$('form#meeting').submit(function () {
	form_ok = true;
	$('form#meeting .inputbox.required input, form#meeting .inputbox.required select').each (function () {
		if(testValidMeeting(this))
			form_ok = false;
	});
	defvalid ($('form#meeting .submitbox input[type=submit]'), form_ok);	
	if (!form_ok)
		setTimeout ("$('form#meeting .submitbox').removeClass('error').children('.err_msg').addClass('hide')",4000);
	
	// ne 2x submit
	if (this.beenSubmitted || !form_ok)
		return false;
	else if (form_ok)
		this.beenSubmitted = true;
});

// vlastni kontrola formulare
function testValidMeeting(el) {
	validerror = false;
	// jmeno
	if ($(el).attr('name')=='jmeno') {
		if(!defvalid (el, $(el).val()))
				validerror = true;
	}
	// email
	if ($(el).attr('name')=='email') {
		val = $(el).val();
		if(!defvalid (el, /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(val)))
			validerror = true;
	}
	// termin
	if ($(el).attr('name')=='termin') {
		if (!defvalid (el, $(el).val()))
			validerror = true;
	}
	// from
	if ($(el).attr('name')=='from') {
		if (!defvalid (el, $(el).val() && $('#m_till').val()))
			validerror = true;
	}
	// till
	if ($(el).attr('name')=='till') {
		if (!defvalid (el, $(el).val() && $('#m_from').val()))
			validerror = true;
	}

	// pocet osob
	/*
	if ($('#m_cbreak').val()!='' && $('#pocet_osob').is(':hidden')) {
		alert ('ahoj');
		$('#pocet_osob').show('blind');
	}
	else if ($('#pocet_osob').is(':visible'))
		$('#pocet_osob').hide('blind');
		*/	
	// kom_protirobotum
	if ($(el).attr('name')=='kom_protirobotum') {
		if (!defvalid (el, $(el).val()==4))
			validerror = true;
	}
	return validerror;
}

// prepinani formulare transferu
$('#meeting_order').click (function (e) {
	$(this).hide();
	$('#meeting').show('blind',null,1000);
	e.preventDefault();
});
$('#meeting').hide();
//$('#pocet_osob').hide();

// kalendar u tranferu
$('#m_termin').datepicker({
	numberOfMonths: 1,
	minDate: 0, 
	maxDate: '+1Y',
	showAnim: null,
	duration:0,
	dateFormat: 'd. m. yy',
	firstDay: 1
});
$('#cal_meeting').click(function() {
	$('#m_termin').datepicker('show');
});

/* --------------------------------------------------------------- */

/* END */
});

// cc check
function cc_check(number, type)	{
	if (number == '' || !/^[0-9 ]+$/.test(number))
		return false;
	
	// inspired by http://www.eflo.net/downloads.php#mod10
	var ccno = number.replace(/ /g, '');
	var cclen = ccno.length;
	var ccsum = 0;
	for (var i=0; i < cclen; i++) {
		var ccdig = parseInt(ccno.charAt(cclen-(i+1)));
		if (i % 2 == 1) {
			ccdig *= 2;
			if (ccdig >= 10) {
				ccdig = (1+ccdig % 10);
			} 
		}
		ccsum += ccdig;
	}
	if (ccsum % 10 != 0) {
		return false;
	}
	switch (type) {
		case 'American Express': return length_correct(number, 13, 15) && /^34|^37/.test(number); // American Express
		
		case 'VISA': return (/^450875|^484406|^484407|^484408|^484411|^484412|^484413|^484414|^484415|^484416|^484417|^484418|^484419|^48442|^48443|^48444|^484450|^484451|^484452|^484453|^484454|^484455|^49173|^49174|^49175|^491880/.test(number) ? false : length_correct(number, 13, 16) && /^4/.test(number)); // VISA
		
		case 'Master/Euro Card': return length_correct(number, 16) && /^51|^52|^53|^54|^55/.test(number); // EC/MC
		
		default: return true;
	}
}
function length_correct(number, valid_length1) {
	for (var i=1; i < arguments.length; i++) {
		if (number.length == arguments[i]) {
			return true;
		}
	}
	return false;
}

// Prepinani poctu poli podle vybrane karty pri rezervaci
function changeCard() {
	i = document.form1.card_type.selectedIndex
	card = document.form1.card_type.options[i].value
	if(card == "American Express") {
		document.form1.card_num4.style.display="none";
		document.getElementById('f_card_num2').setAttribute('maxLength', 6);
		document.getElementById('f_card_num3').setAttribute('maxLength', 5);
		document.getElementById('f_card_num2').setAttribute('Size', 6);
		document.getElementById('f_card_num3').setAttribute('Size', 5);
		//document.getElementById('cvctr').style.display="none";
		}
	else {
		document.form1.card_num4.style.display="inline";
		document.getElementById('f_card_num2').setAttribute('maxLength', 4);
		document.getElementById('f_card_num3').setAttribute('maxLength', 4);
		document.getElementById('f_card_num2').setAttribute('Size', 4);
		document.getElementById('f_card_num3').setAttribute('Size', 4);
		//document.getElementById('cvctr').style.display="block";
		}
	}

/* --------------------------------------------------------------- */

/*!
 * jQuery corner plugin: simple corner rounding
 * Examples and documentation at: http://jquery.malsup.com/corner/
 * version 2.10 (05-MAY-2010)
 * Requires jQuery v1.3.2 or later
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * Authors: Dave Methvin and Mike Alsup
 */

/**
 *  corner() takes a single string argument:  $('#myDiv').corner("effect corners width")
 *
 *  effect:  name of the effect to apply, such as round, bevel, notch, bite, etc (default is round). 
 *  corners: one or more of: top, bottom, tr, tl, br, or bl.  (default is all corners)
 *  width:   width of the effect; in the case of rounded corners this is the radius. 
 *           specify this value using the px suffix such as 10px (yes, it must be pixels).
 */
;(function($) { 

var style = document.createElement('div').style;
var moz = style['MozBorderRadius'] !== undefined;
var webkit = style['WebkitBorderRadius'] !== undefined;
var radius = style['borderRadius'] !== undefined || style['BorderRadius'] !== undefined;
var mode = document.documentMode || 0;
var noBottomFold = $.browser.msie && (($.browser.version < 8 && !mode) || mode < 8);

var expr = $.browser.msie && (function() {
    var div = document.createElement('div');
    try { div.style.setExpression('width','0+0'); div.style.removeExpression('width'); }
    catch(e) { return false; }
    return true;
})();
    
function sz(el, p) { 
    return parseInt($.css(el,p))||0; 
};
function hex2(s) {
    var s = parseInt(s).toString(16);
    return ( s.length < 2 ) ? '0'+s : s;
};
function gpc(node) {
    while(node) {
        var v = $.css(node,'backgroundColor');
        if (v && v != 'transparent' && v != 'rgba(0, 0, 0, 0)') {
	        if (v.indexOf('rgb') >= 0) { 
	            var rgb = v.match(/\d+/g); 
	            return '#'+ hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
	        }
            return v;
		}
		if (node.nodeName.toLowerCase() == 'html')
		    break;
		node = node.parentNode; // keep walking if transparent
    }
    return '#ffffff';
};

function getWidth(fx, i, width) {
    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 'dogfold':
    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 'bevelfold':
    case 'bevel':  return i+1;
    }
};

$.fn.corner = function(options) {
    // in 1.3+ we can fix mistakes with the ready state
	if (this.length == 0) {
        if (!$.isReady && this.selector) {
            var s = this.selector, c = this.context;
            $(function() {
                $(s,c).corner(options);
            });
        }
        return this;
	}

    return this.each(function(index){
		var $this = $(this);
		// meta values override options
		var o = [$this.attr($.fn.corner.defaults.metaAttr) || '', options || ''].join(' ').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|bevelfold|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dogfold|dog/;
		var fx = ((o.match(re)||['round'])[0]);
		var fold = /dogfold|bevelfold/.test(o);
		var edges = { T:0, B:1 };
		var opts = {
			TL:  /top|tl|left/.test(o),       TR:  /top|tr|right/.test(o),
			BL:  /bottom|bl|left/.test(o),    BR:  /bottom|br|right/.test(o)
		};
		if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
			opts = { TL:1, TR:1, BL:1, BR:1 };
			
		// support native rounding
		if ($.fn.corner.defaults.useNative && fx == 'round' && (radius || moz || webkit) && !cc && !sc) {
			if (opts.TL)
				$this.css(radius ? 'border-top-left-radius' : moz ? '-moz-border-radius-topleft' : '-webkit-border-top-left-radius', width + 'px');
			if (opts.TR)
				$this.css(radius ? 'border-top-right-radius' : moz ? '-moz-border-radius-topright' : '-webkit-border-top-right-radius', width + 'px');
			if (opts.BL)
				$this.css(radius ? 'border-bottom-left-radius' : moz ? '-moz-border-radius-bottomleft' : '-webkit-border-bottom-left-radius', width + 'px');
			if (opts.BR)
				$this.css(radius ? 'border-bottom-right-radius' : moz ? '-moz-border-radius-bottomright' : '-webkit-border-bottom-right-radius', width + 'px');
			return;
		}
			
		var strip = document.createElement('div');
		$(strip).css({
			overflow: 'hidden',
			height: '1px',
			minHeight: '1px',
			fontSize: '1px',
			backgroundColor: sc || 'transparent',
			borderStyle: 'solid'
		});
	
        var pad = {
            T: parseInt($.css(this,'paddingTop'))||0,     R: parseInt($.css(this,'paddingRight'))||0,
            B: parseInt($.css(this,'paddingBottom'))||0,  L: parseInt($.css(this,'paddingLeft'))||0
        };

        if (typeof this.style.zoom != undefined) this.style.zoom = 1; // force 'hasLayout' in IE
        if (!keep) this.style.border = 'none';
        strip.style.borderColor = cc || gpc(this.parentNode);
        var cssHeight = $(this).outerHeight();

        for (var j in edges) {
            var bot = edges[j];
            // only add stips if needed
            if ((bot && (opts.BL || opts.BR)) || (!bot && (opts.TL || opts.TR))) {
                strip.style.borderStyle = 'none '+(opts[j+'R']?'solid':'none')+' none '+(opts[j+'L']?'solid':'none');
                var d = document.createElement('div');
                $(d).addClass('jquery-corner');
                var ds = d.style;

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

                if (bot && cssHeight != 'auto') {
                    if ($.css(this,'position') == 'static')
                        this.style.position = 'relative';
                    ds.position = 'absolute';
                    ds.bottom = ds.left = ds.padding = ds.margin = '0';
                    if (expr)
                        ds.setExpression('width', 'this.parentNode.offsetWidth');
                    else
                        ds.width = '100%';
                }
                else if (!bot && $.browser.msie) {
                    if ($.css(this,'position') == 'static')
                        this.style.position = 'relative';
                    ds.position = 'absolute';
                    ds.top = ds.left = ds.right = ds.padding = ds.margin = '0';
                    
                    // fix ie6 problem when blocked element has a border width
                    if (expr) {
                        var bw = sz(this,'borderLeftWidth') + sz(this,'borderRightWidth');
                        ds.setExpression('width', 'this.parentNode.offsetWidth - '+bw+'+ "px"');
                    }
                    else
                        ds.width = '100%';
                }
                else {
                	ds.position = 'relative';
                    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,getWidth(fx,i, width));
                    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);
                }
				
				if (fold && $.support.boxModel) {
					if (bot && noBottomFold) continue;
					for (var c in opts) {
						if (!opts[c]) continue;
						if (bot && (c == 'TL' || c == 'TR')) continue;
						if (!bot && (c == 'BL' || c == 'BR')) continue;
						
						var common = { position: 'absolute', border: 'none', margin: 0, padding: 0, overflow: 'hidden', backgroundColor: strip.style.borderColor };
						var $horz = $('<div/>').css(common).css({ width: width + 'px', height: '1px' });
						switch(c) {
						case 'TL': $horz.css({ bottom: 0, left: 0 }); break;
						case 'TR': $horz.css({ bottom: 0, right: 0 }); break;
						case 'BL': $horz.css({ top: 0, left: 0 }); break;
						case 'BR': $horz.css({ top: 0, right: 0 }); break;
						}
						d.appendChild($horz[0]);
						
						var $vert = $('<div/>').css(common).css({ top: 0, bottom: 0, width: '1px', height: width + 'px' });
						switch(c) {
						case 'TL': $vert.css({ left: width }); break;
						case 'TR': $vert.css({ right: width }); break;
						case 'BL': $vert.css({ left: width }); break;
						case 'BR': $vert.css({ right: width }); break;
						}
						d.appendChild($vert[0]);
					}
				}
            }
        }
    });
};

$.fn.uncorner = function() { 
	if (radius || moz || webkit)
		this.css(radius ? 'border-radius' : moz ? '-moz-border-radius' : '-webkit-border-radius', 0);
	$('div.jquery-corner', this).remove();
	return this;
};

// expose options
$.fn.corner.defaults = {
	useNative: true, // true if plugin should attempt to use native browser support for border radius rounding
	metaAttr:  'data-corner' // name of meta attribute to use for options
};
    
})(jQuery);


/*
 * A time picker for jQuery
 * Based on original timePicker by Sam Collet (http://www.texotela.co.uk) -
 * copyright (c) 2006 Sam Collett (http://www.texotela.co.uk)
 *
 * Dual licensed under the MIT and GPL licenses.
 * Copyright (c) 2009 Anders Fajerson
 * @name     timePicker
 * @version  0.2
 * @author   Anders Fajerson (http://perifer.se)
 * @example  $("#mytime").timePicker();
 * @example  $("#mytime").timePicker({step:30, startTime:"15:00", endTime:"18:00"});
 */

(function($){
  $.fn.timePicker = function(options) {
    // Build main options before element iteration
    var settings = $.extend({}, $.fn.timePicker.defaults, options);

    return this.each(function() {
      $.timePicker(this, settings);
    });
  };

  $.timePicker = function (elm, settings) {
    var e = $(elm)[0];
    return e.timePicker || (e.timePicker = new jQuery._timePicker(e, settings));
  };

  $._timePicker = function(elm, settings) {

    var tpOver = false;
    var keyDown = false;
    var startTime = timeToDate(settings.startTime, settings);
    var endTime = timeToDate(settings.endTime, settings);

    $(elm).attr('autocomplete', 'OFF'); // Disable browser autocomplete

    var times = [];
    var time = new Date(startTime); // Create a new date object.
    while(time <= endTime) {
      times[times.length] = formatTime(time, settings);
      time = new Date(time.setMinutes(time.getMinutes() + settings.step));
    }

    var $tpDiv = $('<div class="time-picker'+ (settings.show24Hours ? '' : ' time-picker-12hours') +'"></div>');
    var $tpList = $('<ul></ul>');

    // Build the list.
    for(var i = 0; i < times.length; i++) {
      $tpList.append("<li>" + times[i] + "</li>");
    }
    $tpDiv.append($tpList);
    // Append the timPicker to the body and position it.
    var elmOffset = $(elm).offset();
    //$tpDiv.appendTo('body').css({'top':elmOffset.top, 'left':elmOffset.left}).hide();
		$tpDiv.appendTo($(elm).parent()).hide();

    // Store the mouse state, used by the blur event. Use mouseover instead of
    // mousedown since Opera fires blur before mousedown.
    $tpDiv.mouseover(function() {
      tpOver = true;
    }).mouseout(function() {
      tpOver = false;
    });

    $("li", $tpList).mouseover(function() {
      if (!keyDown) {
        $("li.selected", $tpDiv).removeClass("selected");
        $(this).addClass("selected");
      }
    }).mousedown(function() {
       tpOver = true;
    }).click(function() {
      setTimeVal(elm, this, $tpDiv, settings);
      tpOver = false;
    });

    var showPicker = function() {
      if ($tpDiv.is(":visible")) {
        return false;
      }
      $("li", $tpDiv).removeClass("selected");

      // Show picker. This has to be done before scrollTop is set since that
      // can't be done on hidden elements.
      $tpDiv.show();

      // Try to find a time in the list that matches the entered time.
      var time = elm.value ? timeStringToDate(elm.value, settings) : startTime;
      var startMin = startTime.getHours() * 60 + startTime.getMinutes();
      var min = (time.getHours() * 60 + time.getMinutes()) - startMin;
      var steps = Math.round(min / settings.step);
      var roundTime = normaliseTime(new Date(0, 0, 0, 0, (steps * settings.step + startMin), 0));
      roundTime = (startTime < roundTime && roundTime <= endTime) ? roundTime : startTime;
      var $matchedTime = $("li:contains(" + formatTime(roundTime, settings) + ")", $tpDiv);

      if ($matchedTime.length) {
        $matchedTime.addClass("selected");
        // Scroll to matched time.
        $tpDiv[0].scrollTop = $matchedTime[0].offsetTop;
      }
      return true;
    };
    // Attach to click as well as focus so timePicker can be shown again when
    // clicking on the input when it already has focus.
    $(elm).focus(showPicker).click(showPicker);
    // Hide timepicker on blur
    $(elm).blur(function() {
      if (!tpOver) {
        $tpDiv.hide();
      }
    });
    // Keypress doesn't repeat on Safari for non-text keys.
    // Keydown doesn't repeat on Firefox and Opera on Mac.
    // Using kepress for Opera and Firefox and keydown for the rest seems to
    // work with up/down/enter/esc.
    var event = ($.browser.opera || $.browser.mozilla) ? 'keypress' : 'keydown';
    $(elm)[event](function(e) {
      var $selected;
      keyDown = true;
      var top = $tpDiv[0].scrollTop;
      switch (e.keyCode) {
        case 38: // Up arrow.
          // Just show picker if it's hidden.
          if (showPicker()) {
            return false;
          };
          $selected = $("li.selected", $tpList);
          var prev = $selected.prev().addClass("selected")[0];
          if (prev) {
            $selected.removeClass("selected");
            // Scroll item into view.
            if (prev.offsetTop < top) {
              $tpDiv[0].scrollTop = top - prev.offsetHeight;
            }
          }
          else {
            // Loop to next item.
            $selected.removeClass("selected");
            prev = $("li:last", $tpList).addClass("selected")[0];
            $tpDiv[0].scrollTop = prev.offsetTop - prev.offsetHeight;
          }
          return false;
          break;
        case 40: // Down arrow, similar in behaviour to up arrow.
          if (showPicker()) {
            return false;
          };
          $selected = $("li.selected", $tpList);
          var next = $selected.next().addClass("selected")[0];
          if (next) {
            $selected.removeClass("selected");
            if (next.offsetTop + next.offsetHeight > top + $tpDiv[0].offsetHeight) {
              $tpDiv[0].scrollTop = top + next.offsetHeight;
            }
          }
          else {
            $selected.removeClass("selected");
            next = $("li:first", $tpList).addClass("selected")[0];
            $tpDiv[0].scrollTop = 0;
          }
          return false;
          break;
        case 13: // Enter
          if ($tpDiv.is(":visible")) {
            var sel = $("li.selected", $tpList)[0];
            setTimeVal(elm, sel, $tpDiv, settings);
          }
          return false;
          break;
        case 27: // Esc
          $tpDiv.hide();
          return false;
          break;
      }
      return true;
    });
    $(elm).keyup(function(e) {
      keyDown = false;
    });
    // Helper function to get an inputs current time as Date object.
    // Returns a Date object.
    this.getTime = function() {
      return timeStringToDate(elm.value, settings);
    };
    // Helper function to set a time input.
    // Takes a Date object.
    this.setTime = function(time) {
      elm.value = formatTime(normaliseTime(time), settings);
      // Trigger element's change events.
      $(elm).change();
    };

  }; // End fn;

  // Plugin defaults.
  $.fn.timePicker.defaults = {
    step:30,
    startTime: new Date(0, 0, 0, 0, 0, 0),
    endTime: new Date(0, 0, 0, 23, 30, 0),
    separator: ':',
    show24Hours: true
  };

  // Private functions.

  function setTimeVal(elm, sel, $tpDiv, settings) {
    // Update input field
    elm.value = $(sel).text();
    // Trigger element's change events.
    $(elm).change();
    // Keep focus for all but IE (which doesn't like it)
    if (!$.browser.msie) {
      elm.focus();
    }
    // Hide picker
    $tpDiv.hide();
  }

  function formatTime(time, settings) {
    var h = time.getHours();
    var hours = settings.show24Hours ? h : (((h + 11) % 12) + 1);
    var minutes = time.getMinutes();
    return formatNumber(hours) + settings.separator + formatNumber(minutes) + (settings.show24Hours ? '' : ((h < 12) ? ' AM' : ' PM'));
  }

  function formatNumber(value) {
    return (value < 10 ? '0' : '') + value;
  }

  function timeToDate(input, settings) {
    return (typeof input == 'object') ? normaliseTime(input) : timeStringToDate(input, settings);
  }

  function timeStringToDate(input, settings) {
    if (input) {
      var array = input.split(settings.separator);
      var hours = parseFloat(array[0]);
      var minutes = parseFloat(array[1]);

      // Convert AM/PM hour to 24-hour format.
      if (!settings.show24Hours) {
        if (hours === 12 && input.substr('AM') !== -1) {
          hours = 0;
        }
        else if (hours !== 12 && input.indexOf('PM') !== -1) {
          hours += 12;
        }
      }
      var time = new Date(0, 0, 0, hours, minutes, 0);
      return normaliseTime(time);
    }
    return null;
  }

  /* Normalise time object to a common date. */
  function normaliseTime(time) {
    time.setFullYear(2001);
    time.setMonth(0);
    time.setDate(0);
    return time;
  }

})(jQuery);