/*
* 
* jbgallery 1.0
* @requires jQuery v1.3.2
* 
* Copyright (c) 2009 Massimiliano Balestrieri
* Examples and docs at: http://maxb.net/blog/
* Licensed GPL licenses:
* http://www.gnu.org/licenses/gpl.html
*
* Inspired by http://www.ringvemedia.com/introduction
*/

//jQuery.noConflict();

; (function($) {


    jBGallery = {};

    jBGallery.Init = function(options, data) {
        if (typeof options == "string") {
            if (jBGallery.Api.enabled(this) || options === 'enable' || options === 'destroy')

                return jBGallery.Api[options](this, data);
        } else {
            return this.each(function(nr) {
                new jBGallery.Core(this, options, nr);
            });
        }
    };

    jBGallery.Api = {
        enabled: function(el) {
            return $(el).data("enabled");
        },
        current: function(el) {
            return $(el).data("current");
        },
        go: function(el, nr) {
            return $(el).trigger("go", [nr]);
        },
        left: function(el) {
            return $(el).trigger("left");
        },
        right: function(el) {
            return $(el).trigger("right");
        },
        play: function(el, interval) {
            return $(el).trigger("play", [interval]);
        },
        stop: function(el) {
            return $(el).trigger("stop");
        },
        disable: function(el) {
            return $(el).trigger("disable");
        },
        enable: function(el) {
            return $(el).trigger("enable");
        },
        destroy: function(el) {
            return $(el).trigger("destroy");
        }
    };



    jBGallery.Core = function(el, options, nr) {
        var _metadata = {};
        if ($.metadata)
            _metadata = $(el).metadata();

        var _options = $.extend({
            style: "zoom", //centered, zoom    
            slideshow: false,
            interval: 4000,
            fade_time: 400,
            fade: true,
            menu: 'simple', //false, numbers, simple
            shortcuts: [37, 39],
            after: function(ev) { },
            before: function() { },
            load: function(ev) { },
            close: function() { },
            popup: false,
            labels: {},
            log: function() { } //_log//
        }, _metadata, options);

        if (!_options.fade)
            _options.fade_time = 0;

        var that = el;
        var _id = nr;

        $("#jbgallery-css").removeAttr("disabled");


        //nascondo l'ul - x ie
        $(that).find("ul").hide();

        var _imgs = $.map($(that).find("ul > li > a"), function(a, i) {
            //fix numbers
            if (_options.menu == "numbers")
                $(a).text((i + 1));

            return { href: a.href, title: a.title, target: a.target };
        });

        var _current_url = _imgs[0].href; //(_current - 1)//$(that).find("a").eq(0).attr("href");
        var _current_title = _imgs[0].title; //(_current - 1)//$(that).find("a").eq(0).attr("href");
        var _current_target = _imgs[0].target;



        $(that).prepend('<div id="jbg"><a target="' + _current_target + '" href="' + _current_title + '"><img class="' + _options.style + '" id="jbgallery_target" src="' + _current_url + '" /></a></div>');


        var _target = $("#jbgallery_target", that);

        //centered
        if (_options.style == "centered") {
            $("#jbg").css({ "top": "auto", height: "100%" });
            $("#jbg").height("100%");
        }

        jBGallery.OnLoadImage(that, _options, _target);

        if (_imgs.length > 1)
            new jBGallery.Engine(that, _options, _target, _id, _imgs);


        function _log(arg) {
            if (window.console)
                console.log(arg);
            else
                alert(arg);
        }

    };

    //NEW
    jBGallery.slideshow = false;
    jBGallery.interval = false;
    jBGallery.timeout = false;

    jBGallery.OnLoadImage = function(that, _options, _target) {

        var _is_webkit = navigator.userAgent.toLowerCase().search(/webkit/) != -1;
        var _is_ie6 = /MSIE 6/i.test(navigator.userAgent); //navigator.userAgent.toLowerCase().search(/msie/) != -1;

        _target.bind("load", function(ev) {
            _options.log("jBGallery.OnLoadImage : load");
            _onload(ev);
            _options.load(ev);
            _options.after(ev);

            //TEST
            if (jBGallery.slideshow) {
                clearTimeout(jBGallery.timeout);
                jBGallery.timeout = setTimeout(function() {
                    $(that).trigger("right", [jBGallery.interval]);
                }, jBGallery.interval);
            }
        });

        if (_is_webkit || _is_ie6 || _options.style == "centered") {
            jBGallery.Fix(that, _options, _target, _is_ie6, _options.style == "centered");
        }

        function _onload(ev) {
            _options.log("ev: _onload");
            $("#jbg-loading").hide();
            _appear(ev);
        }

        function _appear(ev) {
            _options.log("ev: _appear");
            _target.fadeIn(_options.fade_time);
        }


    };


    jBGallery.Fix = function(that, _options, _target, _is_ie6, _centered) {
        //alert("fix?");
        var _resize_timer = null;
        var _el = _target.get(0);

        $(window).bind('resize', function(ev) {
            if (_resize_timer) clearTimeout(_resize_timer);
            _resize_timer = setTimeout(function() {
                _options.log("resize: _fix_dimensions");
                _fix(ev);
            }, 100);
        });

        _target.bind('load', function(ev) {
            _fix(ev);
        });


        function _fix(ev) {
            if (_centered) {
                _fix_bigimage(ev);
            }
            else if (_is_ie6) {
                _target.height("auto").width("auto");
                setTimeout(_fix_dimensions, 10);
            } else {
                _fix_dimensions(ev);
            }
        }

        function _fix_bigimage(ev) {
            _options.log("jBGallery.Fix: load/fix_bigimage");
            $(_target).width("auto").height("auto");
            var _dim = _get_dimensions();
            if (_dim.h > _dim.bh || _dim.w > _dim.bw) {
                if (_dim.p <= 1) {//immagine alta -> larghezza
                    $(_target).width(_dim.bw);
                } else if (_dim.p > 1) {//immagine larga -> altezza
                    $(_target).height(_dim.bh);
                }
            }
        }

        function _fix_dimensions(ev) {
            _options.log("jBGallery.Fix: load/fix_dimensions");
            //TODO
            if ($("#jbgallery-css").size() == 0) {
                alert("load css");
                return;
            }
            var _dim = _get_dimensions();
            if (_is_ie6) {
                if (_dim.h < _dim.bh || _dim.w < _dim.bw) {
                    if (_dim.p == 1) {//immagine 1x1 -> monitor
                        if (_dim.pm > 1) {
                            $(_target).width(_dim.bw);
                        } else {
                            $(_target).height(_dim.bh);
                        }
                    } else if (_dim.p < 1) {//immagine alta -> larghezza
                        $(_target).width("100%");
                    } else if (_dim.p > 1) {//immagine larga -> altezza
                        $(_target).height("100%");
                    }
                }
            } else {//webkit
                //if(_dim.h < _dim.bh)
                //$(_target).height(_dim.bh);
            }

        }


        function _get_dimensions() {
            var bw = $("body").width();
            var bh = $("body").height();
            var pm = bw / bh;
            var p = _el.width / _el.height;
            return { bw: bw, bh: bh, pm: pm, p: p, h: _el.height, w: _el.width };
        }
    };

    jBGallery.Engine = function(that, _options, _target, _id, _imgs) {

        var _current = 1; //start 1 not 0
        var _enabled = true;

        //TODO: var _slideshow = false;
        jBGallery.interval = _options.interval;

        //public attr
        jBGallery.Data(that, "current", _current);
        jBGallery.Data(that, "enabled", true);

        //events
        $(that)
    .bind("play", _play)
	.bind("stop", _stop)
	.bind("right", _right)
	.bind("left", _left)
	.bind("go", _go)
	.bind("enable", _enable)
	.bind("disable", _disable)
	.bind("destroy", _destroy);


        _menu();
        _keys();
        _unload();
        _loading();

        if (_options.slideshow)
            _play();

        function _menu() {
            //console.log(_options.menu);
            if (_options.menu) {
                new jBGallery.SimpleMenu(that, _options, _id);
            } else {
                $(that).find("ul").hide(); //mmmh or remove
            }
        }

        function _keys() {
            new jBGallery.Keyboard(that, _options);
        }

        //by _go()
        function _load(nr) {
            _preload();
            _current = jBGallery.Data(that, "current", nr);
            _target.fadeOut(_options.fade_time, function() {
                $(this).hide().attr({ "src": _imgs[(_current - 1)].href }); //.trigger("appear");
                $(this).parent().attr({ "href": _imgs[(_current - 1)].title });
                $(this).parent().attr({ "target": _imgs[(_current - 1)].target });
            });

        }

        // ------------ EVENTS -------------------------

        var _timestamp = 0;
        var _timer_go = 1;

        function _play(ev, interval) {
            _options.log("jBGallery.Engine: _play");

            if (jBGallery.slideshow)
                return;

            jBGallery.slideshow = true;

            if (interval)
                jBGallery.interval = interval;

            if (ev)
                $(that).trigger("right", [jBGallery.interval]);

            /*
            if(_slideshow)
            return;
            var _interval = interval || _options.interval;
            _slideshow = setInterval(function(){
            _right(ev, _interval);
            }, _interval);*/
        }

        function _stop(ev) {
            _options.log("jBGallery.Engine: _stop");
            jBGallery.slideshow = false;
            clearTimeout(jBGallery.timeout);
            /*
            clearInterval(_slideshow);
            _slideshow = false;
            _options.log(_slideshow);*/
        }

        function _right(ev, _interval) {
            _options.log("jBGallery.Engine: _right");
            if (_current < _imgs.length) {
                var _goto = _current + 1;
            } else {
                var _goto = 1;
            }
            //console.log(_goto);
            $(that).trigger("go", [_goto, _interval]);

        }

        function _left(ev) {
            _options.log("jBGallery.Engine: _left");
            if (_current > 1) {
                var _goto = _current - 1;
            } else {
                var _goto = _imgs.length;
            }
            $(that).trigger("go", [_goto]);
        }

        function _go(ev, nr, _interval) {
            /*if(_slideshow){
            _timer_go = _timestamp ? ev.timeStamp - _timestamp : _interval;
            _timestamp = ev.timeStamp;
            if(_interval && ((_interval - 100) > _timer_go)){
            _options.log("Skip go elapsed only : " + _timer_go + " Interval: " + _interval);
            return false;
            }
            }*/
            if (jBGallery.slideshow) {
                _timer_go = _timestamp ? ev.timeStamp - _timestamp : _interval; //_interval;
                _timestamp = ev.timeStamp;
                if (_interval && ((_interval - 100) > _timer_go)) {
                    _options.log("Skip go elapsed only : " + _timer_go + " Interval: " + _interval);
                    clearTimeout(jBGallery.timeout);
                    jBGallery.timeout = setTimeout(_do, _interval);
                } else {
                    _options.log("Elapsed : " + _timer_go + " Interval: " + _interval);
                    _do();
                }
            } else {
                _do();
            }

            function _do() {
                _options.log("jBGallery.Engine: _go " + nr);
                _options.before();
                _load(nr);
            }
        }


        function _enable(ev) {
            _options.log("jBGallery.Engine: _enable");
            _enabled = jBgSlide.Data(that, "enabled", true);
        }

        function _disable(ev) {
            _options.log("jBGallery.Engine:_disable");
            _enabled = jBgSlide.Data(that, "enabled", false);
            if (_slideshow)
                _stop();
        }

        function _destroy(ev) {

            jBGallery.slideshow = false;
            clearTimeout(jBGallery.timeout);

            _options.log("jBGallery.Engine:_destroy");

            $("#jbgallery-css").attr("disabled", "disabled"); //remove();
            $("#jbg-loading").remove();
            $("html, body").removeClass("jbg");

            _target.unbind();
            _target.remove();

            var _menu = $("body").find("ul#jbg-menu-" + _id);
            _menu.find("a").unbind();
            _menu.remove();

            $.removeData(that);
            $(that).unbind();
            $("#jbg", that).remove();

            $(document).unbind('keydown#jbgallery');
        }


        function _unload() {
            $(window).unload(function() {
                $(that).trigger("destroy");
            });
        }

        function _loading() {
            $(that).before('<div id="jbg-loading"><span class="jbg-loading"></span></div>');
        }

        function _preload() {
            $("#jbg-loading").show();
        }

    };


    jBGallery.Keyboard = function(that, _options) {

        $(document).bind("keydown#jbgallery", _onkey2);

        function _onkey2(e) {
            _options.log("ev: _onkey");

            if (e == null) { // ie
                keycode = e.keyCode;
            } else { // mozilla
                keycode = e.which;
            }

            var _sc = _options.shortcuts;

            switch (keycode) {
                case _sc[0]:
                    $(that).trigger("left");
                    return false;
                    break;
                case _sc[1]:
                    $(that).trigger("right");
                    return false;
                    break;
                case 37:
                case 38:
                case 39:
                case 40:
                    return false;
                    break;
            }

        }
    };

    jBGallery.SimpleMenu = function(el, _options, _id) {

        var that = el;

        var _target = $(that).find("ul").clone();

        _options.labels = $.extend({
            play: "play",
            next: "next",
            prev: "prev",
            stop: "stop",
            close: "close"
        }, _options.labels);

        if (_options.menu == 'numbers') {
            _target.find("a:eq(0)").addClass("selected").addClass("visited");
            _target.click(_delegation);
        }

        if (_options.menu == 'simple') {
            //$(that)
            _target
            //.find("ul")
        .empty()
        .append(_menu_play())
        .append(_menu_stop());
        }

        _target
    .append(_menu_next())
    .prepend(_menu_prev())
    .addClass("jbg-menu")
    .attr("id", "jbg-menu-" + _id)
    .appendTo("#jbg")//("#jbg-content")
    .show();


        if (_options.popup) {
            _target
        .append(_menu_close());
        }

        if (_options.menu == 'numbers')
            $("#jbgallery_target", that).bind("load", _update_classes);

        function _update_classes(ev) {
            var _nr = $(that).jbgallery("current");
            _target.find("a.selected").removeClass("selected");
            _target.find("a:eq(" + _nr + ")").addClass("visited").addClass("selected");
        }

        function _menu_play() {
            var _el = $('<a href="#" class="jbg-play">' + _options.labels.play + '</a>').click(function() {
                $(that).trigger("play");
                return false;
            });
            return $("<li></li>").append(_el);
        }

        function _menu_stop() {
            var _el = $('<a href="#" class="jbg-stop">' + _options.labels.stop + '</a>').click(function() {
                $(that).trigger("stop");
                return false;
            });
            return $("<li></li>").append(_el);
        }

        function _menu_next() {
            var _el = $('<a href="#" class="jbg-next">' + _options.labels.next + '</a>').click(function() {
                $(that).trigger("right");
                return false;
            });
            return $("<li></li>").append(_el);
        }

        function _menu_prev() {
            var _el = $('<a href="#" class="jbg-prev">' + _options.labels.prev + '</a>').click(function() {
                $(that).trigger("left");
                return false;
            });
            return $("<li></li>").append(_el);
        }

        function _menu_close() {
            var _el = $('<a href="#" class="jbg-close">' + _options.labels.close + '</a>').click(function() {
                $(that).trigger("destroy");
                _options.close();
                return false;
            });
            return $("<li></li>").append(_el);
        }

        function _delegation(ev) {
            var _el = ev.target || ev.srcElement;
            if (_el.tagName.toString().toLowerCase() === 'a') {
                var _num = parseInt($(_el).text());
                $(that).trigger("go", [_num]);
            }
            return false;
        }

    };

    jBGallery.Data = function(that, key, val) {
        if (typeof val !== 'undefined') {
            $(that).data(key, val);
            return val;
        } else {
            return $(that).data(key);
        }
    };

    jBGallery.Css = function(href) {
        $(document.getElementsByTagName("head")[0]).append('<link rel="stylesheet" type="text/css" id="jbgallery-css" media="screen" href="' + href + '" />');
    };

    $.fn.jbgallery = jBGallery.Init;
    $.fn.jbgcss = jBGallery.Css;

})(jQuery);