﻿/// <reference path="jquery-1.4.3.min.js" />
/// <reference path="xtn-1.0.js" />
(function ($) {

    var rq = !($.browser.msie && $.browser.version <= 7);

    var keys = {
        space: 32,
        enter: 13,
        arrows: {
            left: 37,
            up: 38,
            right: 39,
            down: 40
        }
    };

    $.fn.scrollTo = function (settings) {
        var config = {
            parent: $(document.body),
            delay: 0
        };
        if (settings) $.extend(config, settings);

        $(this).each(function () {
            var y = $(this).position().top;
            xtn.fn.log("[ui] scroll " + y);
            config.parent.stop().delay(config.delay).animate({ scrollTop: '+=' + y }, 100);
        });

    };

    $.fn.tabs = function (settings) {
        var config = {
            onSelect: function (el, indx) { }
        };

        if (settings) $.extend(config, settings);

        // private functions
        var fn = {
            switchTo: function (context, config, index) {

                xtn.fn.cookie.set('xtn-tc', context.attr('id'));
                xtn.fn.cookie.set('xtn-ti', index);

                $("li a", context).each(function (indx) {
                    $(this).removeClass("ui-tab-active");
                    if (indx == index) {
                        $(this).addClass("ui-tab-active");
                    }
                });

                var current = undefined;

                $("div.ui-tab-content", context.parent()).each(function (indx) {
                    $(this).addClass("ui-tab-hide");
                    if (indx == index) {
                        current = $(this).removeClass("ui-tab-hide");
                    }
                });

                if (config.onSelect) {
                    config.onSelect.call(context, current, index);
                }
            }
        };

        this.each(function () {

            var context = $(this).wrap($("<div />").addClass("ui-tabs-wrapper"));

            $("li div.ui-tab-content", this).detach().appendTo($(this).parent());

            var firstTab = 0;

            if (xtn.fn.cookie.get('xtn-tc') == context.attr('id')) {
                var c = parseInt(xtn.fn.cookie.get('xtn-ti'));
                if (!c) c = 0;
                firstTab = c;
            }

            $("li a", context)
                .click(function () {
                    location.hash = '#/' + $(this).attr('id') + '/';
                    return false;
                })
                .each(function (indx) {

                    if (indx == 0) $(this).parent().addClass("ui-tab-first");

                    var rel = $(this).text().toLowerCase().replace(/[^a-zA-Z 0-9]+/g, '').replace(/ +/g, '_');

                    $(this).attr("id", 'tab-' + rel).attr("index", indx);

                    if (indx == firstTab) {
                        firstTab = $(this).attr('id');
                    }
                });

            xtn.fn.hash.callbacks.add(/tab-[a-z0-9_]+/g, function (hash, matched) {
                var id = hash[0].replace(/\/+/g, '').replace('#', '');

                var a = $("#" + id);

                if (!$(a).hasClass("ui-tab-active")) {
                    fn.switchTo(context, config, parseInt(a.attr("index")));
                }
            });

            xtn.fn.hash.goPartial(/tab-[a-z0-9]+/g, firstTab);

        });

        return this;
    };


    $.fn.progress = function (settings) {
        var config = {};

        if (settings) $.extend(config, settings);

        $(this).each(function () {

            var lis = $("li", $(this));
            var length = lis.length - 1;

            lis.each(function (indx) {
                var li = $(this);

                if (indx == 0) {
                    li.addClass("ui-progress-item-first");
                }

                if (indx == length) {
                    li.addClass("ui-progress-item-last");
                }

                var full = li.hasClass("ui-progress-item-history") || li.hasClass("ui-progress-current");
                var n = $(this).next();

                if (full && (n.hasClass("ui-progress-item-history") || n.hasClass("ui-progress-current"))) {
                    $(this).addClass("ui-progress-item-status-full");
                } else if (full && !(n.hasClass("ui-progress-item-history") || n.hasClass("ui-progress-current"))) {
                    $(this).addClass("ui-progress-item-status-half");
                } else {
                    $(this).addClass("ui-progress-item-status-none");
                }

                if (rq) {
                    var s = $(".ui-progress-text", li);
                    s.css({ marginTop: ((li.height() - s.height()) / 2) + 'px' });
                }

                $(this).addClass("ui-progress-item");
            });

        });

        return this;
    };


    var methods = {
        init: function () { },
        _handleEvent: function (e, ele, ui) {
            e.bind(ele, function () {
                if (e.data('ui-event')) e.removeClass(e.data('ui-event'));
                e.data('ui-event', 'ui-event-' + ele)
                e.addClass(e.data('ui-event'));
                ui.trigger(ele, [ui[0]])
            });
        },
        checkbox: function (settings) {
            var config = {
                events: ['click', 'blur', 'focus']
            };

            if (settings) $.extend(config, settings);

            $(this).each(function () {
                var chck = $(this).css({ display: 'none' });

                var s = $("<span />").addClass("ui-block").html("&nbsp;");
                var e = $("<a />")
                    .attr({ href: '#' })
                    .addClass("ui-form-checkbox ui-block-inline clickable")
                    .append(s)
                    .click(function () {
                        xtn.fn.log("[ui] checkbox clicked: " + chck.attr('id'));
                        if (chck.is(":checked")) {
                            s.removeClass("ui-form-checked");
                        } else {
                            s.addClass("ui-form-checked");
                        }
                        return false;
                    })
                    .keydown(function (eventObj) {
                        if (eventObj.keyCode == keys.space) $(this).click();
                    });

                jQuery.each(config.events, function (indx, ele) {
                    methods._handleEvent(e, ele, chck);
                });

                if (!rq) {
                    e.css({ float: 'left' });
                }

                var lbl = chck.next();

                if (lbl.is("label")) {
                    lbl.addClass("ui-form-checkbox-label");
                }

                if (chck.is(":checked")) {
                    s.addClass("ui-form-checked");
                }

                e.insertAfter(chck);
                chck.data('ui-control', e);
            });
            return this;
        },
        radio: function (settings) {
            var config = {
                events: ['click', 'blur', 'focus']
            };

            if (settings) $.extend(config, settings);

            var fn = {
                update: function (name) {
                    $("input[name='" + name + "']").each(function () {
                        var rd = $(this);
                        var ui = rd.data('ui-control');
                        if (rd.is(":checked")) {
                            $("span", ui).addClass("ui-form-checked");
                        } else {
                            $("span", ui).removeClass("ui-form-checked");
                        }
                    });
                }
            };

            $(this).each(function () {
                var rd = $(this).css({ display: 'none' });

                var s = $("<span />").addClass("ui-block").html("&nbsp;");
                var e = $("<a />")
                    .attr({ href: '#' })
                    .addClass("ui-form-radio ui-block-inline clickable")
                    .click(function () {

                        xtn.fn.log("[ui] radio clicked: " + rd.attr('id'));

                        if (s.hasClass("ui-form-checked")) {
                            return false; /* if active do nothing */
                        } else {
                            rd.attr('checked', 'checked');

                        }

                        /* check to see if we need to update any elements */
                        if (rd.attr('name') != '') fn.update(rd.attr('name'));

                        return false;
                    })
                    .keydown(function (eventObj) {
                        if (eventObj.keyCode == keys.space) $(this).click();
                    })
                    .append(s);

                jQuery.each(config.events, function (indx, ele) {
                    methods._handleEvent(e, ele, rd);
                });

                var lbl = rd.next();

                if (lbl.is("label")) {
                    lbl.addClass("ui-form-radio-label");
                }

                if (rd.is(":checked")) {
                    s.addClass("ui-form-checked");
                }

                e.insertAfter(rd);
                rd.data('ui-control', e);
            });
            return this;
        },
        text: function (settings) {
            var config = {
                padding: {
                    X: 6,
                    Y: 8
                },
                className: 'ui-form-text-single'
                /* events not needed, only styling elements */
            };

            if (settings) $.extend(config, settings);

            $(this).each(function () {
                var txt = $(this);

                txt.addClass(config.className);

                if (!txt.hasClass('ui-form-fixed')) { // check if we need to expand or not
                    txt.css({ width: (txt.parent().innerWidth() - config.padding.X) + 'px' });
                }

            });

            return this;
        },
        dropdown: function (settings) {
            var config = {
                padding: {
                    X: 4,
                    Y: 6
                },
                ani: {
                    list: 'normal'
                },
                events: ['blur', 'focus', 'change']
            };

            if (settings) $.extend(config, settings);

            var fn = {
                bodyClick: function (e) {
                    var drp = e.data[0];
                    var ui = drp.data('ui-control');
                    var u = ui.data('ui-list');
                    u.slideUp(config.ani.list);

                    $(document.body).unbind('click', fn.bodyClick);
                },
                select: function (a, drp, navigate) {

                    var hasChanged = drp.val() == '' ? false : a.data('value') != drp.val();
                    drp.val(a.data('value'));

                    $("option:selected", drp).removeAttr("selected");
                    a.data('ui-control').attr('selected', 'selected');

                    var ui = drp.data('ui-control');

                    $("span.ui-form-dropdown-text", ui).html(a.html());

                    var u = ui.data('ui-list');

                    $("a", u).removeClass("ui-active");
                    a.addClass("ui-active");

                    a.scrollTo({ parent: u });

                    if (!navigate) {
                        u.slideUp(config.ani.list);
                        // call onchange function programatically
                        if (hasChanged) $("a", ui).trigger('change', [drp]);

                        $(document.body).unbind('click', fn.bodyClick);
                    }

                    return false;
                }
            };

            $(this).each(function () {
                var drp = $(this).css({ display: 'none' });

                var u = $("<ul />").addClass("ui-form-dropdown-list");

                var e = $("<a />")
                            .attr('href', '#')
                            .addClass("ui-form-dropdown-current ui-block clickable")
                            .append(
                                $("<span />").addClass("ui-form-dropdown-text ui-block").html("&nbsp;")
                            )
                            .append(
                                $("<span />").addClass("ui-form-dropdown-icon").html("&nbsp;")
                            );

                var w = $("<div />")
                        .addClass("ui-form-dropdown-wrapper")
                        .append(e);

                if (drp.attr("disabled")) {
                    var dis = $("<div />").addClass("ui-form-dropdown-disabled").html("&nbsp;");
                    w.append(dis);
                }
                e.click(function () {

                    var holla = function () {
                        u.css({ top: (w.height() + w.offset().top) + 'px', left: w.offset().left + 'px' });

                        $(document).data('ui-list', u);
                        u.slideToggle(config.ani.list, function () {
                            if (u.is(":visible")) {
                                $("a.ui-active", u).scrollTo({ parent: u, delay: 100 });
                                $(document.body).bind('click', [drp], fn.bodyClick);
                            }
                        });
                    };

                    if ($(document).data('ui-list')) {
                        var old = $(document).data('ui-list');
                        if (old != u)
                            old.slideUp(config.ani.list, holla);
                        else
                            holla.call(this);
                    } else holla.call(this);

                    return false;
                }).keydown(function (eventObj) {
                    
                    if (drp.attr("disabled")) return;

                    switch (eventObj.which) {
                        case keys.arrows.down:
                            drp.data('search', '');
                            if (u.is(":visible")) {
                                var l = $("a.ui-active", u).parent().next();
                                $("a", l)
                                    .trigger('click', [true]);
                                eventObj.preventDefault();
                            } else {
                                $(this).click();
                                $(document.body).bind('click', [drp], fn.bodyClick);
                            }
                            break;
                        case keys.arrows.up:
                            drp.data('search', '');
                            if (u.is(":visible")) {
                                var l = $("a.ui-active", u).parent().prev();
                                $("a", l).trigger('click', [true]);
                                eventObj.preventDefault();
                            }
                            break;
                        case keys.arrows.left:
                        case keys.arrows.right:
                            drp.data('search', '');
                            break;
                        case keys.enter:
                            drp.data('search', '');
                            e.trigger('change', [drp]);
                            $("a.ui-active", u).trigger('click');
                            eventObj.preventDefault();
                            break;
                        default:
                            if (!drp.data('search')) drp.data('search', '');

                            drp.data('search', drp.data('search') + String.fromCharCode(eventObj.which));
                            xtn.fn.log(drp.data('search'));

                            var filter = drp.data('search');
                            var reg = new RegExp('^' + filter, "ig")
                            var has = false;
                            $("option", drp).each(function () {
                                if (!has && $(this).text().search(reg) > -1) {
                                    $(this).data('ui-control').trigger('click', [true]);
                                    has = true;
                                }
                            });

                            break;
                    }

                }).blur(function () {
                    drp.data('search', '');
                });

                jQuery.each(config.events, function (indx, ele) {
                    methods._handleEvent(e, ele, drp);
                });

                if (!drp.hasClass('ui-form-fixed')) { // check if we need to expand or not
                    w.css({ width: (drp.parent().innerWidth() - config.padding.X) + 'px' });
                }

                w.data('ui-list', u);
                drp.data('ui-control', w);

                u.insertAfter(drp);
                w.insertAfter(drp);

                u.css({ width: (w.innerWidth() - 2) + 'px' });

                var liWidth = u.width();

                if (drp.hasClass('ui-form-dropdown-split') && rq) {
                    u.addClass('ui-form-dropdown-split');
                    liWidth /= 2;
                    if ($("option", drp).length > 9) {
                        liWidth -= 9;
                    }
                    xtn.fn.log(liWidth);
                }

                $("option", drp).each(function () {
                    var opt = $(this);

                    var a = $("<a />")
                                .data('value', opt.val())
                                .data('ui-control', opt)
                                .attr('href', '#')
                                .addClass("ui-block")
                                .html(opt.html())
                                .click(function (o, i) { return fn.select(a, drp, i); });

                    opt.data('ui-control', a);

                    var li =
                        $("<li />")
                        .append(a)
                        .css({ width: liWidth + 'px' });

                    u.append(li);

                    if (opt.attr('selected')) {
                        fn.select(a, drp, true);
                    }
                });

            });

            return this;
        }
    };


    $.fn.transform = function (method) {
        // Method calling logic
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.elevate');
        }
    };


    xtn.extend({
        helpers: {
            // xtn.helpers.transform(document.body);
            // this is just a helper function to transform all form elements into their js-counter parts
            transform: function (e) {
                var context = $(e);
                $("input[type='checkbox']", context).transform('checkbox');
                $("input[type='radio']", context).transform('radio');
                $("input[type='text'], input[type='password'] ", context).transform('text');
                $("textarea", context).transform('text', { className: 'ui-form-text-multi' });
                $("select", context).transform('dropdown');
            }
        }
    }, xtn.fn);

})(jQuery);

