$.widget("nw.customScroll", {
    options: {
        resizeWidth: false,
        resizeHeight: false,
        outerMarginWidth: 0,
        outerMarginHeight: 0,
        scrollbarSize: 20,
        scrollbarMargin: 5,
        boxHeight: 0,
        isHorizontal: false,
        enableClick: false,
        scrollbarPos: "",
        forcedTotalContent: 0,
        forcedTotalContentFunc: null,
        forcedVisibleSize: 0
    },


    caller: null,
    content: null,
    sc: null,
    sb: null,
    sbh: null,
    hovn: null,
    hovp: null,
    scroller: null,
    totalContent: 0,
    draggerContainerHeight: 0,
    animSpeed: 400,
    easeType: "easeOutCirc",
    targY: 0,
    draggerHeight: 20,
    visibleHeight: 0,
    visibleWidth: 0,
    calcWidth: 0,
    calcHeight: 0,
    originalWidth: 0,
    originalHeight: 0,


    _setOption: function (key, value) {
        this.options[key] = value;
    },

    _scroll: function () {
        var pointer = this;
        if (!pointer.options.isHorizontal) {
            var scrollAmount = (pointer.totalContent - pointer.visibleHeight) / (pointer.draggerContainerHeight - pointer.draggerHeight);
            var draggerY = $(pointer.sbh).position().top;
            pointer.targY = -draggerY * scrollAmount;
            var thePos = $(pointer.scroller).position().top - pointer.targY;
            $(pointer.scroller).stop().animate({ top: "-=" + thePos }, pointer.animSpeed, pointer.easeType);
        } else {
            var scrollAmount = (pointer.totalContent - pointer.visibleWidth) / (pointer.draggerContainerHeight - pointer.draggerHeight);
            var draggerX = $(pointer.sbh).position().left;
            pointer.targX = -draggerX * scrollAmount;
            var thePos = $(pointer.scroller).position().left - pointer.targX;
            $(pointer.scroller).stop().animate({ left: "-=" + thePos }, pointer.animSpeed, pointer.easeType);
        }
    },

    _resyncHandle: function () {
        var pointer = this;
        var scrollerpos = Math.abs($(pointer.scroller).position().left);
        var ratio = scrollerpos / (pointer.totalContent - pointer.visibleWidth);
        var handleleft = pointer.draggerContainerHeight * ratio;
        handleleft -= (pointer.draggerHeight / 2);
        $(pointer.sbh).stop().animate({ left: Math.floor(handleleft) }, pointer.animSpeed, pointer.easeType);
    },

    _scrollTo: function (scrollQty) {
        var pointer = this;
        if (!pointer.options.isHorizontal) {
            //da fare
        } else {
            var nextleft = $(pointer.scroller).position().left - scrollQty;
            if (nextleft > 0) {
                $(pointer.scroller).stop().animate({ left: "0" }, pointer.animSpeed, pointer.easeType);
                $(pointer.sbh).stop().animate({ left: "0" }, pointer.animSpeed, pointer.easeType);
            } else {
                if (nextleft < ((pointer.totalContent - pointer.visibleWidth) * -1)) {
                    var maxright = (pointer.totalContent - pointer.visibleWidth) * -1
                    $(pointer.scroller).stop().animate({ left: maxright }, pointer.animSpeed, pointer.easeType);
                    $(pointer.sbh).stop().animate({ left: (pointer.draggerContainerHeight - pointer.draggerHeight) }, pointer.animSpeed, pointer.easeType);
                } else {
                    $(pointer.scroller).stop().animate({ left: "-=" + scrollQty }, pointer.animSpeed, pointer.easeType, function () { pointer._resyncHandle() });

                }
            }
        }
    },

    _scrollTop: function () {
        var pointer = this;
        var scrollAmount = 0;
        $(pointer.sbh).css("top", "0px");
        $(pointer.scroller).stop().css("top", "0px");
    },

    _scrollLeft: function () {
        var pointer = this;
        var scrollAmount = 0;
        $(pointer.sbh).css("left", "0px");
        $(pointer.scroller).stop().css("left", "0px");
    },

    _stopScroll: function () {

    },

    refresh: function () {
        this._onResize();
    },

    _onResize: function () {
        var pointer = this;
        pointer._beforeRebuild();
        var w = pointer.originalWidth;
        var h = pointer.originalHeight;
        if (pointer.options.resizeWidth) {
            w = $(window).width() - this.options.outerMarginWidth;
        }
        if (pointer.options.resizeHeight) {
            h = $(window).height() - this.options.outerMarginHeight;
        }
        pointer._build(w, h);
    },

    _build: function (w, h) {
        var pointer = this;
        pointer.visibleHeight = h;
        pointer.visibleWidth = w;

        if (pointer.options.isHorizontal) {
            if (pointer.options.scrollbarPos == "") {
                pointer.options.scrollbarPos = "right"
            }
        } else {
            if (pointer.options.scrollbarPos == "") {
                pointer.options.scrollbarPos = "bottom"
            }
        }

        if (pointer.options.isHorizontal) {
            $(pointer.content).height(h);
        } else {
            $(pointer.content).width(w - (this.options.scrollbarSize + (this.options.scrollbarMargin * 2)));
        }

        $(pointer.caller).css("overflow", "visible");

        if (pointer.options.isHorizontal) {
            $(pointer.sc).width(w);
            $(pointer.sc).height(h + (this.options.scrollbarSize + (this.options.scrollbarMargin * 2)));
        } else {
            $(pointer.sc).width(w);
            $(pointer.sc).height(h);
        }

        $(pointer.scroller).width($(pointer.content).width());
        $(pointer.scroller).height($(pointer.content).height());

        if (pointer.options.enableClick) {
            if (pointer.options.isHorizontal) {
                $(pointer.hovp).width(Math.floor(w / 2));
                $(pointer.hovp).height(h);
                $(pointer.hovn).width(Math.floor(w / 2));
                $(pointer.hovn).height(h);
                $(pointer.hovp).css("top", "0px");
                $(pointer.hovn).css("top", "0px");
                $(pointer.hovp).css("left", "0px");
                $(pointer.hovn).css("right", "0px");

                $(pointer.hovp).unbind("click").click(function () {
                    pointer._scrollTo((Math.floor(w / 2) * -1));
                });
                $(pointer.hovn).unbind("click").click(function () {
                    pointer._scrollTo(Math.floor(w / 2));
                });
            } else {
            }
        }

        if (pointer.options.isHorizontal) {
            $(pointer.sb).width(w - (this.options.scrollbarMargin * 2));
            //if ($(pointer.content).width() > w) {
            if (pointer.options.forcedTotalContent > 0) {
                pointer.totalContent = pointer.options.forcedTotalContent;
            } else if (pointer.options.forcedTotalContentFunc) {
                pointer.totalContent = pointer.options.forcedTotalContentFunc();
            } else {
                pointer.totalContent = $(pointer.content).width();
            }
            if (pointer.totalContent > w) {
                pointer.draggerContainerHeight = $(pointer.sb).width();
                pointer.draggerHeight = $(pointer.sbh).width();

                $(pointer.sbh).draggable({
                    axis: "x",
                    containment: "parent",
                    drag: function (event, ui) {
                        pointer._scroll();
                    },
                    stop: function (event, ui) {
                        pointer._stopScroll();
                    }
                });
                $(pointer.sb).click(function (e) {
                    var mouseCoord = (e.pageX - $(this).offset().left);
                    $(pointer.sbh).css("left", mouseCoord - (pointer.draggerHeight / 2));
                    pointer._scroll();
                });

                /*
                $(function($) {
                $(pointer.sc).bind("mousewheel", function(event, delta) {
                vel = Math.abs(delta*10);
                $(pointer.sbh).css("left", $(pointer.sbh).position().left-(delta*vel));
                pointer._scroll();
                if($(pointer.sbh).position().left<0){
                $(pointer.sbh).css("left", 0);
                $(sc).stop();
                pointer._scroll();
                }
                if($(pointer.sbh).position().left > pointer.draggerContainerHeight - pointer.draggerHeight){
                $(pointer.sbh).css("left", pointer.draggerContainerHeight - pointer.draggerHeight);
                $(pointer.sc).stop();
                pointer._scroll();
                }
                return false;
                });
                });
                */
                $(pointer.sb).show();
            } else {
                $(pointer.sb).hide();
            }
        } else {
            $(pointer.sb).height(h - (this.options.scrollbarMargin * 2));
            //if ($(pointer.content).height() > h) {
            if (pointer.options.forcedTotalContent > 0) {
                pointer.totalContent = pointer.options.forcedTotalContent;
            } else if (pointer.options.forcedTotalContentFunc) {
                pointer.totalContent = pointer.options.forcedTotalContentFunc();
            } else {
                pointer.totalContent = $(pointer.content).height();
            }
            if (pointer.totalContent > h) {
                pointer.draggerContainerHeight = $(pointer.sb).height();
                pointer.draggerHeight = $(pointer.sbh).height();
                $(pointer.sbh).draggable({
                    axis: "y",
                    containment: "parent",
                    drag: function (event, ui) {
                        pointer._scroll();
                    },
                    stop: function (event, ui) {
                        pointer._stopScroll();
                    }
                });
                $(pointer.sb).click(function (e) {
                    var mouseCoord = (e.pageY - $(this).offset().top);
                    var targetPos = mouseCoord + pointer.draggerHeight;
                    if (targetPos < pointer.draggerContainerHeight) {
                        $(pointer.sbh).css("top", mouseCoord);
                        pointer._scroll();
                    } else {
                        $(pointer.sbh).css("top", pointer.draggerContainerHeight - pointer.draggerHeight);
                        pointer._scroll();
                    }
                });
                /*
                $(function($) {
                $(pointer.sc).bind("mousewheel", function(event, delta) {
                vel = Math.abs(delta*10);
                $(pointer.sbh).css("top", $(pointer.sbh).position().top-(delta*vel));
                pointer._scroll();
                if($(pointer.sbh).position().top<0){
                $(pointer.sbh).css("top", 0);
                $(sc).stop();
                pointer._scroll();
                }
                if($(pointer.sbh).position().top > pointer.draggerContainerHeight - pointer.draggerHeight){
                $(pointer.sbh).css("top", pointer.draggerContainerHeight - pointer.draggerHeight);
                $(pointer.sc).stop();
                pointer._scroll();
                }
                return false;
                });
                });
                */
                $(pointer.sb).show();
            } else {
                $(pointer.sb).hide();
            }
        }
    },

    _init: function () {
        var pointer = this;
        pointer.caller = $(this.element);
        pointer.content = $(pointer.caller).children().first();
        $(pointer.content).addClass("nwScrollContent");
        pointer.originalWidth = $(pointer.caller).width();
        pointer.originalHeight = $(pointer.caller).height();
        var scro = $("<div class=\"nwScrollScroller\"></div>");
        $(pointer.content).wrap(scro);
        pointer.scroller = $(pointer.content).parent();

        var cont = $("<div class=\"nwScrollContainer\"></div>");
        $(pointer.scroller).wrap(cont);
        pointer.sc = $(pointer.scroller).parent();
        if (pointer.options.isHorizontal) {
            if (pointer.options.scrollbarPos == "top") {
                $(pointer.sc).addClass("nwScrollHTop");
            } else {
                $(pointer.sc).addClass("nwScrollH");
            }
        } else {
            if (pointer.options.scrollbarPos == "left") {
                $(pointer.sc).addClass("nwScrollVLeft");
            } else {
                $(pointer.sc).addClass("nwScrollV");
            }
        }

        var scrb = $("<div class=\"nwScrollbar\"><div class=\"nwScrollbarHandle\">&nbsp;</div></div>");
        $(pointer.sc).append(scrb);

        pointer.sb = $(pointer.sc).find(".nwScrollbar");
        pointer.sbh = $(pointer.sb).find(".nwScrollbarHandle");

        if (pointer.options.enableClick) {
            var ho_next = $("<div class=\"nwScrollHoverNext\"></div>");
            $(pointer.sc).append(ho_next);
            pointer.hovn = $(pointer.sc).find(".nwScrollHoverNext");
            var ho_prev = $("<div class=\"nwScrollHoverPrev\"></div>");
            $(pointer.sc).append(ho_prev);
            pointer.hovp = $(pointer.sc).find(".nwScrollHoverPrev");
        }

        if (pointer.options.resizeWidth || pointer.options.resizeHeight) {
            var resizeTimeOut = false;
            $(window).resize(function () {
                if (resizeTimeOut !== false) { clearTimeout(resizeTimeOut); }
                resizeTimeOut = setTimeout(function () { pointer._onResize() }, 400);
            });
            pointer._onResize();
        } else {
            pointer._build(pointer.originalWidth, pointer.originalHeight);
        }
    },

    _beforeRebuild: function () {
        if (this.options.isHorizontal) {
            this._scrollLeft();
        } else {
            this._scrollTop();
        }
    },

    destroy: function () {
        // call the base destroy function
        $.Widget.prototype.destroy.call(this);
    }
});

