/*
* 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 = [];
        times[0] = settings.blank_option;
        var time;        
        time = new Date(startTime); // Create a new date object.
//        alert("appt_start--->"+settings.appt_start)
        while(time <= endTime) {
//			alert("time--->"+time+"\n after formatting-->"+formatTime(time, settings))
            times[times.length] = formatTime(time, settings);
            time = new Date(time.setMinutes(time.getMinutes() + settings.step));
        }
        var $tpDiv = $('<div id="app_s_time" 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);
        var leftpos = 0;
        var toppos = 0;
        // Append the timPicker to the body and position it.
        var elmOffset = $(elm).offset();
        var parentDiv = '';
        //	alert($(elm).parent().html());
        //alert(elmOffset);
        $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) : settings.scrollTo;
	if (elm.value == '(Any)') {
		time = elm.value;
	}
	if (time == settings.blank_option) {
		var $matchedTime = $("li:contains(" + settings.blank_option + ")", $tpDiv);
	}
	else {
		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.
		var scroll_position = $matchedTime[0].offsetTop;
		var aa = $tpDiv[0].scrollTop;
		$tpDiv[0].scrollTop = scroll_position;
	}

    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,
    blank_option: '(None)',
    scrollTo: new Date(0, 0, 0, 12, 0, 0)
};

// Private functions.

function setTimeVal(elm, sel, $tpDiv, settings) {
    // Update input field    
    elm.value = $(sel).text();
    // Check if a blank value entered
    if(elm.value == settings.blank_option)
        elm.value = (settings.blank_option == '(Any)') ? '(Any)' : ''
    
// 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.indexOf('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);    