/*global jQuery */
(function($) {
    /**
     * Events:
     * 	- lowwatermark - triggered once stream is scrolled past the guard
     *  - emptystream - triggered if stream is empty after content is appended
     * 					or when checkEmpty method is called on empty stream
     *  - streamchange - triggered if resurce(s) are appended
     */
    $.fn.dynScroll = function(params) {

        params = $.extend({
            formatter: function (resource) {
                return $('<div>' + resource + '</div>');
            },
            appendGuard: function (pos, len) {
                return (pos == Math.round(len / 2));
            },
            guardFormatter: function () {
                return $('<div class="dyn_guard"></div>');
            },
            appendToContainer: null,
            jscrollParams: { showArrows: true, scrollbarWidth: 15, maintainPosition: true }
        }, params);

        return this.each(function() {
            var $this = $(this);
            var pane_container = $this.parents().filter(".jScrollPaneContainer");

            if (!params['appendToContainer']) {
                params['appendToContainer'] = $this;
            }
            $this.data("ds_params", params);

            $this.bind("dragdown", function () {
                var guard = $('.dyn_guard', $this);
                if (guard.length == 0) {
                    return;
                }

                var tlow = pane_container.offset().top + pane_container.innerHeight();
                var gpos = guard.offset().top;

                if (gpos <= tlow) {
                    guard.remove();
                    $this.trigger("lowwatermark");
                }
            });

            // -----------------------------------------------------------------
            // 	Public API
            // -----------------------------------------------------------------
            this.init = function (wait) {
                if (typeof wait == 'number' && wait > 0) {
                    var img = $("img", $this.data("ds_params")['appendToContainer']);
                    var loaded = true;

                    for (var i = 0; i < img.length; i++) {
                        if (!img[i].complete) {
                            loaded = false;
                            break;
                        }
                    }

                    if (!loaded) {
                        setTimeout(function () {
                            $this[0].init(wait - 1);
                        }, 300);
                    } else {
                        $this.jScrollPane($this.data("ds_params")['jscrollParams']);
                        pane_container = $this.parents().filter(".jScrollPaneContainer");
                    }
                } else {
                    $this.jScrollPane($this.data("ds_params")['jscrollParams']);
                    pane_container = $this.parents().filter(".jScrollPaneContainer");
                }
            };

            this.appendResources = function (resources) {
                var data = $this.data("ds_params");
                if (resources) {
                    var formatter = data['formatter'];
                    var doGuard = data['appendGuard'];
                    var guardFormat = data['guardFormatter'];
                    var len = resources.length;
                    var append_container = data['appendToContainer'];

                    for (var i = 0; i < len; i++) {
                        append_container.append(formatter(resources[i]));
                        if (doGuard(i, len)) {
                            append_container.append(guardFormat());
                        }
                    }

                    $this[0].init(($("img",append_container).length == 0) ? 0 : 7);
                    $this.trigger("streamchange");
                }
            };

            this.appendHTML = function (html) {
                if (html && $.trim(html) != '') {
                    var obj = $(html);
                    var guardFormatter = $this.data("ds_params")['guardFormatter'];
                    var append_container = $this.data("ds_params")['appendToContainer'];

                    append_container.append(obj);

                    if (obj.length > 2) {
                        guardFormatter().insertAfter(obj[Math.round(obj.length / 2)]);
                    }

                    $this[0].init(($("img", append_container).length == 0) ? 0 : 7);
                    $this.trigger("streamchange");
                }
            };

            this.checkEmpty = function () {
                /* XXX: This should be done on the server-side
                if ($('>', $this.data("ds_params")['appendToContainer']).length == 0) {
                    $this.trigger("emptystream");
                }
                */
            };

            this.clearContent = function (trigger_watermark) {
                var data = $this.data("ds_params")['appendToContainer'].empty();
                if (trigger_watermark) {
                    $this.trigger("lowwatermark");
                }
            };

            this.init(0);
        });
    };
})(jQuery);