/**
 * @author Stefan Kendlbacher
 */
(function($){
    $.fn.panoramic = function(options){
        var defaults = {
            dummy: "dummy.png"
        };
        var opts = $.extend({}, defaults, options);
        var holder_width, holder_height, holder_top, holder_left, image_src, image_width, image_height, that;
        var set_dummy_image = function(){
            that.attr("src", opts.dummy);
        };
        var set_bg_image = function(){
            that.css({
                background: "url(" + image_src + ")"
            });
        };
        var interval = null, steps = 25, time_interval_value = 50, percent = 0.08;
        var nav_elements_css = {
            background: "url(alpha_image.png)",
            fontSize: "18px",
            fontWeight: "bold",
            textAlign: "center",
            cursor: "pointer",
            color: "#fff"
        };
        var get_css = function(){
            return nav_elements_css;
        };
        var nav_elements;
        var set_elements = function(){
            nav_elements = {
                main: {
                    id: "navigator",
                    css: {
                        position: "absolute",
                        top: holder_top,
                        left: holder_left,
                        width: holder_width + "px",
                        height: holder_height + "px"
                    }
                },
                left: {
                    id: "left",
                    html: "&larr;",
                    css: {
                        float: "left"
                    }
                },
                right: {
                    id: "right",
                    html: "&rarr;",
                    css: {
                        float: "right"
                    }
                },
                downward: {
                    id: "down",
                    html: "&darr;",
                    css: {
                        clear: "both"
                    }
                },
                upward: {
                    id: "up",
                    html: "&uarr;"
                }
            };
        };
        
        var create_navigation = function(){
            set_elements();
            var div = $("<div />", nav_elements.main);
            var extra = false;
            var lis = [];
            lis[0] = $("<div />", nav_elements.left);
            lis[1] = $("<div />", nav_elements.right);
            if (image_height > holder_height) {
                var tmp_l = lis[0], tmp_2 = lis[1];
                lis = [];
                lis[0] = $("<div />", nav_elements.upward);
                lis[1] = tmp_l;
                lis[2] = tmp_2;
                lis[3] = $("<div />", nav_elements.downward);
                extra = true;
            }
            
            div.appendTo("body");
            $(lis).appendTo(div);
            
            var left_css = get_css();
            
            left_css.height = holder_height;
            left_css.lineHeight = holder_height + "px";
            left_css.width = percent * holder_width;
            
            if (extra) {
                var upward_css = get_css();
                upward_css.height = percent * holder_height;
                upward_css.lineHeight = percent * holder_height + "px";
                $(lis[0]).css(upward_css);
                $(lis[0]).css({
                    width: holder_width
                });
                var downward_css = upward_css;
                
                $(lis[3]).css(downward_css);
                $(lis[3]).css({
                    width: holder_width
                });
                left_css.height = holder_height - 2 * percent * holder_height + "px";
                left_css.lineHeight = holder_height - 2 * percent * holder_height + "px";
            }
            else {
            
            
            }
            
            $(lis[1]).css(left_css);
            
            var right_css = left_css;
            right_css.float = "right";
            $(lis[2]).css(right_css);
            $(lis).each(function(i, item){
            
                $(item).mouseout(mouse_up).mouseover(mouse_down);
                $(item).hover(function(){
                    $(this).animate({
                        opacity: 1
                    }, "fast");
                }, function(){
                    $(this).animate({
                        opacity: 0
                    }, "slow");
                });
            });
        };
        var get_steps = function(){
            return steps;
        };
        var move_left = function(){
            set_xy(get_steps(), "x");
            img_animate();
        };
        var move_right = function(){
            set_xy(-(get_steps()), "x");
            img_animate();
        };
        var move_up = function(){
            set_xy(get_steps(), "y");
            img_animate();
        };
        var move_down = function(){
            set_xy(-(get_steps()), "y");
            img_animate();
        };
        var navigators = {
            "right": move_right,
            "left": move_left,
            "up": move_up,
            "down": move_down
        };
        var img_animate = function(){
            that.stop();
            that.animate(bg, time_interval_value);
        };
        var bg = {
            "backgroundPosition": "0px 0px"
        };
        var get_xy = function(){
            var x = bg.backgroundPosition.split(" ")[0];
            var y = bg.backgroundPosition.split(" ")[1];
            return {
                x: parseInt(x, 10),
                y: parseInt(y, 10)
            };
        };
        var set_xy = function(value, type){
            var current_pos = get_xy(), new_pos;
            var reset = false;
            if (value < 0) {
                reset = true;
            }
            if (type === "x") {
                new_pos = current_pos.x + value;
                if (new_pos >= -(image_width - holder_width) && new_pos <= 0) {
                    bg.backgroundPosition = create_bgpos([new_pos, current_pos.y]);
                }
                else {
                    if (reset === true) {
                        bg.backgroundPosition = create_bgpos([-(image_width - holder_width), current_pos.y]);
                    }
                    else {
                        bg.backgroundPosition = create_bgpos([0, current_pos.y]);
                    }
                }
            }
            else {
                new_pos = current_pos.y + value;
                if (new_pos >= -(image_height - holder_height) && new_pos <= 0) {
                    bg.backgroundPosition = create_bgpos([current_pos.x, new_pos]);
                }
                else {
                    if (reset === true) {
                        bg.backgroundPosition = create_bgpos([current_pos.x, -(image_height - holder_height)]);
                    }
                    else {
                        bg.backgroundPosition = create_bgpos([current_pos.x, 0]);
                    }
                }
            }
        };
        var create_bgpos = function(xyarray){
            var x = String(xyarray[0]) + "px", y = String(xyarray[1]) + "px";
            return [x, y].join(" ");
        };
        var mouse_down = function(o){
            var id = $(o.currentTarget).attr("id");
            navigators[id].call();
            interval = window.setInterval(navigators[id], time_interval_value);
        };
        var mouse_up = function(){
            window.clearInterval(interval);
        };
        var set_image = function(){
            var loader = new Image();
            loader.src = image_src;
            
            $(loader).load(init);
        };
        var init = function(){
            image_width = this.width;
            image_height = this.height;
            set_dummy_image();
            set_bg_image();
            create_navigation();
            that.show();
        };
        return this.each(function(){
            that = $(this);
            image_src = that.attr("src");
            that.removeAttr("src");
            holder_width = that.width();
            holder_height = that.height();
            holder_top = that.offset().top;
            holder_left = that.offset().left;
            //that.hide();
            css = {
                background: "#ccc"
            };
            that.css(css);
            set_image();
        });
    };
})(jQuery);
