/*
* jQuery.timeSelect - Easy choose time from list using jQuery.
* Date: 1/11/2013
* @author Maxim Litskevich
* @version 0.3
* For the correct work to be add Date.js plugin to the page. http://www.datejs.com/
* If you want that content scrolled near the value of element, you can add jQuery.ScrollTo plugin to the page. http://flesler.blogspot.ru/
*/

(function($) {
    var methods = {
        asTime: function(n) {
            var str = parseInt(n, 10);
            if (str < 10)
                str = "0" + str;
            return str;
        }
    };
    var timeSelector = function() { };

    timeSelector.prototype = {
        container: null,
        containerid: null,
        triggerElement: null,
        starttime: null,
        endtime: null,
        minutesincrement: null,
        openonfocus: null,

        create: function(index) {
            var $this = this;
            this.containerid = 'ts' + index;
            if ($('#' + this.containerid).size()) return;
            var parent = this.triggerElement.parent();
            var html = "";
            var st = this.starttime.clone();
            do {
                var time = methods.asTime(st.getHours()) + ':' + methods.asTime(st.getMinutes());
                html += '<tr><td class="timeselect" time="' + time + '">' + time + '</td></tr>';
                st.add(this.minutesincrement).minutes();
            } while (st <= this.endtime)
            parent.append('<div class="timeselectparent hpx120" id="' + this.containerid + '"><div class="timeselect hpx120"><table class="timeselect">' + html + '</table></div></div>');
            this.container = $('#' + this.containerid);
            this.triggerElement.attr("autocomplete", "off");
            this.resizeContainer(this);
            $(window).bind('resize.timeselector.id' + $this.containerid, function() {
                $this.resizeContainer($this);
            });
            this.container.disableSelection();
            this.container.find('td.timeselect').bind('click.timeselector.id' + $this.containerid, function() { $this.selectTime($this, $(this)); });
            this.triggerElement.bind('click.timeselector.id' + $this.containerid, function() { $this.show($this); });
            if (this.openonfocus) $(document).ready(function() { $this.triggerElement.bind('focus.timeselector.id' + $this.containerid, function() { $this.show($this); }); });
            if ("keyboard" in $) this.triggerElement.keyboard('Tab', function() { if ($this) $this.hide($this); });
            $(document).bind('click.timeselector.id' + $this.containerid, function(e) {
                if (($this.container.has(e.target)).size() == 0 && !($(e.target).is($this.triggerElement))) $this.hide($this);
            });
        },
        //Функция пересчитывает положение контейнера при изменении размера окна
        resizeContainer: function($this) {
            $this.container.css({
                width: $this.triggerElement.outerWidth() - 2 + 'px',
                left: $this.triggerElement.offset().left + 'px',
                margintop: '1px'
            });
            $this.container.find('div.timeselect').css({
                width: ($this.triggerElement.width() + 20) + 'px'
            });
        },
        //Функция отображает контейнер и скролит значения до бижайшего к текущему
        show: function($this) {
            $this.container.show();
            if ("scrollTo" in $) $this.scrollContainer($this);
        },
        //обработчик клика по времени
        selectTime: function($this, val) {
            $this.triggerElement.val(val.html());
            $this.hide($this);
            $this.triggerElement.trigger('result');
        },

        hide: function($this) {
            $this.container.hide();
        },
        //Функция скролит значения до бижайшего к текущему
        scrollContainer: function($this) {
            var selfh = parseInt($this.triggerElement.val().substring(0, 2), 10);
            var selfm = parseInt($this.triggerElement.val().substring(3, 5), 10);
            var scrolltime = new Date(0, 0, 0, selfh, selfm);
            var scrolltimestring = "";
            var st = $this.starttime.clone();
            var time;
            do {
                if (!scrolltimestring.length && st >= scrolltime) {
                    time = methods.asTime(st.getHours()) + ':' + methods.asTime(st.getMinutes());
                    scrolltimestring = time;
                    break;
                }
                st.add($this.minutesincrement).minutes();
            } while (st <= $this.endtime)
            $this.container.find('div.timeselect').scrollTo('td.timeselect[time = "' + scrolltimestring + '"]');
        } /*,
        dispose: function($this) {
            $(window).unbind('resize.timeselector.id' + $this.containerid);
            $this.triggerElement.unbind('click.timeselector.id' + $this.containerid);
            $this.triggerElement.unbind('focus.timeselector.id' + $this.containerid);
            $(document).unbind('click.timeselector.id' + $this.containerid);
            $this.container.unbind();
            $this.container.remove();
            $this.triggerElement = null;
            $this.starttime = null;
            $this.endtime = null;
            $this.minutesincrement = null;
            $this.openonfocus = null;
            $this.resizeContainer = null;
        }*/
    };

    $.fn.timeSelect = function(options) {
        var settings = $.extend({
            'starth': 0,            //start hours
            'startm': 0,            //start minutes
            'endh': 23,             //end hours
            'endm': 59,             //end minutes
            'minutesincrement': 30, //increment
            'openonfocus': true     //if this setting is true then container will be opened when the element has anyone focus, else container will be opened only by click of element.
        }, options);
        return this.each(function() {
            var self = $(this);
            if (!self.parent()) return;
            var selector = new timeSelector();
            selector.triggerElement = self;
            selector.starttime = new Date(0, 0, 0, settings.starth, settings.startm);
            selector.endtime = new Date(0, 0, 0, settings.endh, settings.endm);
            selector.minutesincrement = settings.minutesincrement;
            selector.openonfocus = settings.openonfocus;
            selector.create($("*").index(self));
        });
    };

    $.fn.extend(
    {
        result: function(a) {
            return this.bind("result", a);
        },
        disableSelection: function() {
            this.each(function() {
                this.onselectstart = function() { return false; };
                this.unselectable = "on";
                jQuery(this).css('-moz-user-select', 'none');
            });
        },
        enableSelection: function() {
            this.each(function() {
                this.onselectstart = function() { };
                this.unselectable = "off";
                jQuery(this).css('-moz-user-select', 'auto');
            });
        }
    });
})(jQuery);