﻿var bNet = {
    log: function (msg, val) {
        try {
            console.log(msg, val);
        } catch (e) { }
    },
    ajax: function (url, data, callback, errorCallback) {
        $.ajax({
            url: url,
            type: "post", dataType: "json",
            data: "{ " + data + " }",
            contentType: "application/json; charset=utf-8",
            success: function (data) {
                if (typeof callback == "function")
                    callback(data);
            },
            error: function (data, message) {
                if (typeof errorCallback == "function")
                    errorCallback(data, message);
            }
        });
    },

    twitter: {
        search: function (tag, callback) {
            var twitterJSON = document.createElement("script");
            twitterJSON.type = "text/javascript";
            twitterJSON.id = "twitterSearchScript";
            //here's the search URL
            twitterJSON.src = "http://search.twitter.com/search.json?rpp=5&callback=" + callback + "&q=%23" + tag;
            document.getElementsByTagName("head")[0].appendChild(twitterJSON);
        }
    },
    
    cookie: {
        create: function (name, value, days) {
            var expires = "";
            if (days) {
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                expires = "; expires=" + date.toGMTString();
            }
            document.cookie = name + "=" + value + expires + "; path=/";
            return value;
        },
        read: function (name) {
            var cName = name + "=";
            var cookies = document.cookie.split(";");
            for (var i = 0; i < cookies.length; i++) {
                var cookie = cookies[i].trim();
                if (cookie.indexOf(cName) == 0)
                    return cookie.substring(cName.length, cookie.length);
            }
            return null;
        }
    }
};

(function ($) {

    /* 
     * A really simple method to see if an element exists in the DOM
    */
    $.fn.exists = function() {
        return $(this).length !== 0;
    };

    /*
    * Placeholder makes the label appear inside the textbox.
    * It will hide the text when the textbox has focus, and show it on blur if the textbox is empty
    * It should be targeted at the parent element that holds the inputs and labels: $("#FormContainer").placeholder()
    */
    $.fn.placeholder = function (options) {
        var defaults = {
            createTitle: true,
            halfFade: true,
            bNetForm: false
        };

        var opts = $.extend(defaults, options);

        return $("input[type=text], input[type=password], textarea", this).each(function () {
            var $this = $(this);
            var $label = $("label[for=" + $this.attr("id") + "]");

            if (opts.bNetForm) {
                $label.insertBefore($this);
            }

            $label
                .css("position", "absolute")
                .click(function () {
                    $this.focus();
                });
                
            //If the input box has a value on page render, hide the label
            if ($this.val() !== "") {
                $label.hide();
            }

            //Title will show up as tooltip
            if (opts.createTitle) {
                $this.attr("title", $label.text());
            }

            if (opts.halfFade) {
                $this.focus(function () {
                    if ($this.val() === "") {
                        $label.fadeTo(200, 0.5);
                    }
                }).blur(function () {
                    if ($this.val() === "") {
                        $label.fadeTo(200, 1);
                    }
                }).keyup(function () {
                    if ($this.val() === "") {
                        $label.show().fadeTo(200, 0.5);
                    } else {
                        $label.fadeTo(200, 0, function() {
                            $label.hide();
                        });
                    }
                });

            } else {
                $this.focus(function () {
                    if ($this.val() === "") {
                        $label.hide();
                    }
                }).blur(function () {
                    if ($this.val() === "") {
                        $label.show();
                    }
                });
            }
        });

    };

    /*
    * BigLink
    * Select an element, and this will find the first anchor tag and make the whole element clickable
    */
    $.fn.biglink = function (options) {

        var defaults = {
            hoverClass: "hover",
            linkClass: null
        };

        var opts = $.extend(defaults, options);

        return $(this).each(function () {
            var $this = $(this);

            //If an element has several links, the user will have to specify which link to get the href from
            var link;
            if (opts.linkClass)
                link = $this.find("a." + opts.linkClass).attr("href");
            else
                link = $this.find("a[href]:first").attr("href"); //If not, we'll grab the href from the first link we find

            //We'll append and remove a hover class, if one is specified
            if (opts.hoverClass !== null) {
                $this.hover(function () {
                    $this.addClass(opts.hoverClass);
                }, function () {
                    $this.removeClass(opts.hoverClass);
                });
            }

            //And the append the onclick-handler for each element
            $this.click(function () {
                location.href = link;
            });
        });

    };

    /* SLIDESHOW */
    $.fn.slideshow = function (options) {

        var defaults = {
            autoScroll: false,
            autoScrollDelay: 5000,
            carousel: false,
            containerId: "SlideShowContainer",
            jump: 1,
            navigation: true,
            navigationClick: function(pos) {},
            responsive: false,
            showPages: false,
            thumbnails: null,
            thumbnailWidth: null,
            transition: "slide" /* slide | fade */
        };

        var opts = $.extend(defaults, options);

        var $this = $(this);
        var count = $this.find("li").length;
        var si; //intervaller
        var pos = 1;
        //First we'll wrap the slideshow in a wrapper that will hide the elements as they dissappear outside the box
        $this.wrap("<div class='slideShowWrapper'></div>");
        var $wrapper = $this.parent();

        //Then we'll wrap it in a second element that will hold the navigation buttons and append them
        $wrapper.wrap("<div id='" + opts.containerId + "' style='position:relative;'></div>");
        $container = $wrapper.parent();
        
        var width = $this.find("li:first").outerWidth() * opts.jump;
        var containerWidth = $this.width();
        if (opts.responsive) {
            width = $wrapper.outerWidth();
            containerWidth = width;
            $this.find("li").css("width", width);

            $(window).resize(function() {
                
                width = $("#" + opts.containerId).outerWidth();
                $wrapper.css("width", "100%");
                $this.css("width", width * count);
                $this.find("li").css("width", width);
                var height = $this.find("li").outerHeight();
                $this.height(height);
                $wrapper.height(height);
                $wrapper.parent().find(".nav").css("top", height / 2 - $(".nav").height() / 2);
            });
        }

        $wrapper.css({
            "overflow": "hidden",
            "position": "relative",
            "width": containerWidth,
            "height": $this.find("li:first").height()
        });

        $container.append("<a class='prev nav'>&lt;</a><a class='next nav'>&gt;</a>");

        $this.css("width", containerWidth * count); //Then we'll make the "ul" element fit all "li"'s horizontally

        var $prev = $container.find(".prev");
        var $next = $container.find(".next");

        //Create the pageCounter if it's set to be on
        var $pageList;
        if (opts.showPages) {
            $pageList = $("<ol>");
            var $thumbnails;
            if (opts.thumbnails)
                $thumbnails = $("#" + opts.thumbnails);

            for (i = 1; i <= count; i++) {
                var $li = $("<li>").data("number", i);
                
                if (opts.thumbnails !== null) {
                    $thumbnails.find("li").eq(i-1).find("img").appendTo($li);
                }

                $pageList.append($li);
            }
            $pageList.find("li").click(function () {
                var newPos = $(this).data("number");
                var move = newPos - pos;
                pos = newPos;
                if (opts.transition === "slide") {
                    scroll("-=" + width * move);
                } else if (opts.transition === "fade") {
                    fade(pos);
                }
                
                if (opts.autoScroll)
                    startInterval();
            });
            $pageList.find(":first").addClass("active");

            if (opts.thumbnails !== null) $thumbnails.remove();

            $pageList.appendTo($container);
        }

        //Then we'll position the buttons to be centered vertically...
        $container.find(".prev, .next").css({
            "position": "absolute",
            "top": function () {
                return ($wrapper.height() / 2) - $(this).height();
            },
            "visibility": opts.navigation ? "visible" : "hidden"
        });
        //... and offset by their own width left/right
        $prev.css("left", "-" + $prev.width() + "px");
        $next.css("right", "-" + $next.width() + "px");

        if (!opts.carousel) $prev.hide();
        if ($this.find("li").length < opts.jump + 1) {
            $prev.hide();
            $next.hide();
        } else {

            $prev.click(function () {
                pos -= opts.jump;
                //we'll reset the timer if autoscrolling is on
                if (opts.autoScroll) {
                    startInterval();
                }
                if (pos === 0 && opts.carousel)
                    pos = count;

                if (opts.transition == "slide") {
                    if (pos === count && opts.carousel) {
                        scroll("-=" + width * (count - 1));
                    } else if (opts.carousel) {
                        scroll("+=" + width);
                    } else {
                        scroll("+=" + width, function () {
                            //We'll show/hide the navigation buttons based on the progress of the slider
                            if (pos === 1) {
                                $prev.hide();
                            }
                            if (pos < count && $next.is(":hidden")) {
                                $next.show();
                            }
                        });
                    }
                } else if (opts.transition == "fade") {
                    fade(pos);
                }
                opts.navigationClick(pos);
            });

            $next.click(function () {
                pos += opts.jump;
                if (pos === count + 1 && opts.carousel) 
                    pos = 1;

                if (opts.autoScroll) 
                    startInterval();
                
                if (opts.transition == "slide") {
                    if (pos === 1 && opts.carousel) {
                        scroll("+=" + width * (count - 1));
                    } else if (opts.carousel) {
                        scroll("-=" + width);
                    } else {
                        scroll("-=" + width, function () {
                            //We'll show/hide the navigation buttons based on the progress of the slider
                            if (pos + opts.jump > count - opts.jump) {
                                $next.hide();
                            }
                            if (pos > 1 && $prev.is(":hidden")) {
                                $prev.show();
                            }
                        });
                    }
                } else if (opts.transition == "fade") {
                    fade(pos);
                }
                opts.navigationClick(pos);
            });
        }

        function scroll(distance, callback) {
            //distance: "+=" == "left"
            //          "-=" == "right"
            $this.animate({ "margin-left": distance }, function () {
                if (callback)
                    callback();
            });

            if (opts.showPages) {
                $pageList.find("li").filter(function() {
                    return $(this).data("number") == pos;
                }).siblings().removeClass("active").end().addClass("active");
            }

        }

        if (opts.transition == "fade") {
            $this.find("li:first")
                .addClass("active")
                .css("z-index", 2)
                .siblings()
                    .css("z-index", -100);
        }

        function fade(num, callback) {
            var $curImage = $this.find(".active");
            var $newImage = $this.find("li:nth-child(" + num + ")");

            $curImage.siblings().css("z-index", -100);
            $newImage.css("z-index", 1);

            $curImage.fadeOut(500, function() {
                $curImage.css("z-index", -100).show().removeClass("active");
                $newImage.css("z-index", 2).addClass("active");
            });
        }

        if (opts.autoScroll) {
            //We'll stop the interval when the window loses focus, and start it back up, when the window gains focus
            $(window).blur(function() {
                clearInterval(si);
            }).focus(function () {
                startInterval();
            });
            startInterval();
        }

        function startInterval() {
            clearInterval(si);
            si = setInterval(function () {
                if ($next.is(":visible"))
                    $next.trigger("click");
            }, opts.autoScrollDelay);
        }

        return $(this);
    };

    /*
    * Autocomplete
    * Apply this to an input, and send in the filtering logic
    * and this will handle arrows, and clicking on an item in the list
    */
    $.fn.autocomplete = function (options) {

        var defaults = {
            hoverClass: "hover",
            listId: "List",
            filter: function($this, $sel) {},
            selectItem: function($this, $sel) {},
            enterPress: function($this) {},
            blur: function() {}
        };

        var opts = $.extend(defaults, options);
        var hoverClass = opts.hoverClass;
        var listId = opts.listId;
        var $this = $(this);
        var st;
        
        if (!$("#" + listId).exists()) {
            $("<ul id='" + listId + "' class='autocompleteList'>").insertAfter($this);
        }

        var $list = $("#" + listId);
        $this.keypress(function(e) {
            switch (e.keyCode) {
                case 13: // enter
                    e.preventDefault();
                    e.stopPropagation();
                    if ($list.find("." + hoverClass).exists()) {
                        opts.selectItem($this, $list.find("." + hoverClass));
                    } else {
                        opts.enterPress($this);
                    }
                    return false;
                case 40: //arrow down
                    if ($list.find("." + hoverClass).next().exists()) {
                        $list
                            .find("." + hoverClass)
                            .removeClass(hoverClass)
                            .next()
                                .addClass(hoverClass);
                    }
                    break;
                case 38: //arrow up
                    if ($list.find("." + hoverClass).prev().exists()) {
                        $list
                            .find("." + hoverClass)
                            .removeClass(hoverClass)
                            .prev()
                                .addClass(hoverClass);
                    }
                    break;
                default:
                    clearTimeout(st);
                    //we only need to filter when user stops typing
                    st = setTimeout(function() {
                        opts.filter($this.val());
                        $list.find("li:first").addClass(hoverClass);
                    }, 100);
                    break;
            }
                            
        }).blur(function() {
            if ($list.find("." + hoverClass).exists())
                opts.blur($this, $list.find("." + hoverClass));
        });

        $list.find("li").die("click").die("hover");
        $list.find("li").live({
            hover: function() {
                $(this).addClass(hoverClass).siblings().removeClass(hoverClass);
            },
            click: function() {
                opts.selectItem($this, $list.find("." + hoverClass));
            }
        });
        

        return $(this);
    };

})(jQuery);
