/*!
 * jQuery Infoboard Plugin
 * Copyright (c) 2010 Rolotec AG
 * Version: 1.0 26.01.2011
 * http://www.rolotec.ch
 *
 * Requires: jQuery v1.4.4 or later
 */

(function($) {
    $.fn.infoboard = function(options) {

        if (typeof options == 'string')
            options = { title: options };

        return this.each(function() {
            var $container = $(this);
            var opts = $.extend(true, {}, $.fn.infoboard.defaults, options || {}, $.metadata ? $frame.metadata() : {});
            opts.opener = $.fn.infoboard.opener;
            var url = opts.url;

            if (opts.pause)
                $container.hover(function() {
                    $container.pause = true;
                }, function() {
                    $container.pause = false;
                });

            $('<div>', {text: opts.loadingText, className: 'loading'}).appendTo($container);

            // grab info stream
            $.getJSONP({
                url: url,
                timeout: 30000,
                error: function(xhr, status, e) {
                    failWhale(e);
                },
                success: function(json) {
                    $container.empty();

                    // show message if no data are available
                    if (json.results.length == 0) {
                        $('<div>', {text: opts.noDataText, className: 'loading'}).appendTo($container);
                        return;
                    }

                    $.each(json.results, function() {
                        $date = $('<div>', {className: 'datetime', text: this.start.substring(0, 6)});
                        $headline = $('<div>', {className: 'headline'}).append($('<strong>', {text: this.title})).append('<br/>' + this.body);
                        $info = $('<div>', {className:'news-ticker-headline gl_pointer'}).append($date).append($headline);
                        $info.appendTo($container);
                        var id = this.id;
                        if (opts.link) {
                            $info.bind("click", function() {
                                opts.opener(opts, id);
                            });
                            $info.bind("mouseenter mouseleave", function() {
                                $(this).toggleClass("entered");
                            });
                        }
                    });

                    // do no animation if less of two infos exists
                    // todo: or better, if height is < 300 ?
                    if (json.results.length < 2)
                        return;

                    // stage first animation
                    setTimeout(go, opts.timeout);
                }
            });

            function failWhale(msg) {
                var $fail = $('<div class="fail">' + msg + '</div>');
                $container.empty().append($fail);
            }

            function go() {
                if ($container.pause) {
                    setTimeout(go, 500);
                    return;
                }
                var $el = $container.children(':first');
                $el.animate(opts.animOut, opts.animOutSpeed, function() {
                    var h = $el.outerHeight();
                    $el.animate({ marginTop: -h }, opts.animInSpeed, function() {
                        $el.css({ marginTop: '7px',    opacity: 1 });
                        $el.show().appendTo($container);
                    });
                    // stage next animation
                    setTimeout(go, opts.timeout);
                });
            }
        });
    };

    $.fn.infoboard.opener = function(opts, id) {
        var options = "scrollbars=yes,menubar=no,resizable=no,location=no,status=no,toolbar=no,width=" + opts.popupWidth + ",height=" + opts.popupHeight;
        var link = opts.link;
        if (id) {
            if (link.substring(link.length - 1, link.length) != "/")
                link += "/";
            link += id;
        }
        // open popup
        window.open(link, opts.title, options);
    };

    $.fn.infoboard.defaults = {
        animOutSpeed: 500,              // speed of animation for top info when removed
        animInSpeed: 500,               // speed of scroll animation for moving infos up
        animOut: { opacity: 0 },        // animation of top info when it is removed
        pause: true,                   // true or false (pause on hover)
        timeout: 4000,                  // delay between info scroll
        loadingText: 'News werden geladen..',  // text wil be shown on loading data in the content
        noDataText: 'Zurzeit sind keine News vorhanden',          // text wil be shown if no data are available
        popupWidth: 1010,                // window width of the popup window of infoboard
        popupHeight: 800                // window height of the popup window of infoboard
    };

    // fn to handle jsonp with timeouts and errors
    // hat tip to Ricardo Tomasi for the timeout logic
    $.getJSONP = function(s) {
        s.dataType = 'jsonp';
        $.ajax(s);

        // figure out what the callback fn is
        var $script = $(document.getElementsByTagName('head')[0].firstChild);
        var url = $script.attr('src') || '';
        var cb = (url.match(/callback=(\w+)/) || [])[1];
        if (!cb)
            return; // bail
        var t = 0, cbFn = window[cb];

        $script[0].onerror = function(e) {
            $script.remove();
            handleError(s, {}, "error", e);
            clearTimeout(t);
        };

        if (!s.timeout)
            return;

        window[cb] = function(json) {
            clearTimeout(t);
            cbFn(json);
            cbFn = null;
        };

        t = setTimeout(function() {
            $script.remove();
            handleError(s, {}, "timeout");
            if (cbFn)
                window[cb] = function() {
                };
        }, s.timeout);

        function handleError(s, o, msg, e) {
            // support jquery versions before and after 1.4.3
            ($.ajax.handleError || $.handleError)(s, o, msg, e);
        }
    }

})(jQuery);

