/*global jQuery SWFUpload*/
(function($) {
    $.fn.mediaPicker = function(params) {
        params = $.extend({
            flash_url: null,
            noovo_resources: [],
            noovo_sets: [],
            web_resources: [],
            popup_upload_target: "/",
            size_limit: "100MB",
            upload_target: null,
            upload_parameters: {},
            noovo_multiselect: false,
            web_multiselect: false
        }, params);

        return this.each(function() {
            var picker = $(this);
            var file_list = picker.find('ul.file_queue');
            var nav_tabs = picker.find("ul.tabs li");
            var tabs = picker.find('div.tab');
            var noovo_picker = null;
            var uploader = null;
            var web_picker = null;
            var noovo_sets = picker.find("select[name=resource_set]");
            var noovo_picker_lock = false;

            // save parameters for the MediaPicker
            picker.data("params", params);

            // make the first tab visible and active
            nav_tabs.eq(0).addClass("active");
            tabs.hide().eq(0).show();

            // make tabs clickable
            nav_tabs.css({
                cursor: "pointer"
            });
            nav_tabs.eq(0).unbind("click").click(function() { picker[0].switchToTab("upload"); });
            nav_tabs.eq(1).unbind("click").click(function() { picker[0].switchToTab("noovo"); });
            nav_tabs.eq(2).unbind("click").click(function() { picker[0].switchToTab("web"); picker[0].webDirty(); });

            // Prevent form submitting from within the widget
            var web_submit = tabs.find(".fetch.button");
            tabs.find("[name=resource_filter]").bind("keypress", function (ev) { return ev.keyCode != 13; });
            tabs.find("input.web_url").bind("keypress", function (ev) {
                if (ev.keyCode == 13) {
                    web_submit.trigger('click');
                    return false;
                } else {
                    return true;
                }
            });

            // get tab references
            uploader = picker.find('div.tab.upload div.fullUploader');
            uploader.fullUploader({
                progress_bar_image: "images/bar.png",
                autostart_upload: true,
                progress_bar_image_width: 700,
                flash_uploader_url: params.flash_url,
                upload_url: params.upload_target,
                upload_parameters: params.upload_parameters,
                popup_upload_url: params.popup_upload_target,
                display_percentage: true
            });

            noovo_picker = tabs.eq(1).find('div.carousel').get(0);
            web_picker = tabs.eq(2).find('div.carousel').get(0);

            // init pickers
            $(noovo_picker).carousel({
                manifest: params.noovo_resources,
                multiselect: params.noovo_multiselect
            });

            $(web_picker).carousel({
                manifest: params.web_resources,
                multiselect: params.web_multiselect
            });

            // hook up proxy for upload events
            uploader.unbind("uploadSuccess").bind("uploadSuccess", function(event, file) {
                picker.trigger("uploadSuccess", [file]);
            }).unbind("uploadSuccess").bind("uploadFailure", function(event, file) {
                picker.trigger("uploadFailure", [file]);
            }).unbind("uploadSuccess").bind("uploadComplete", function() {
                picker.trigger("uploadComplete");
            });

            $(noovo_picker).bind("selectionChange", function () {
                $(picker).trigger("resourceSelect", ["noovo"]);
                return false;
            });
            $(noovo_picker).find("a.add_all").unbind("click").click(function () {
                picker.trigger("addAll", ["noovo"]);
                return false;
            });

            // initialize the sets
            noovo_sets.children().remove();
            for(var i = 0; i < params.noovo_sets.length; i++) {
                noovo_sets.append('<option value="' + params.noovo_sets[i].id + '">' + params.noovo_sets[i].name + '</option>');
            }

            // hook up events on the <select> and <input> tags
            var resource_type = tabs.eq(1).find("select[name=resource_type]");
            var resource_set = tabs.eq(1).find("select[name=resource_set]");
            var resource_filter = tabs.eq(1).find("input[name=resource_filter]");

            var filter_handler = function() {
                picker.trigger("filterChange", [{ type: resource_type.val(), set: resource_set.val(), filter: resource_filter.val() }]);
            }

            resource_type.add(resource_set).unbind("change").change(filter_handler);

            resource_filter.bind("keyup", function () {
                if (!picker[0].lockTimeout()) {
                    setTimeout(function () {
                        filter_handler();
                        picker[0].releaseTimeout();
                    }, 1000);
                }
            });

            $(web_picker).bind("selectionChange", function () {
                $(picker).trigger("resourceSelect", ["web"]);
                return false;
            });
            $(web_picker).find("a.add_all").unbind("click").click(function () {
                picker.trigger("addAll", ["web"]);
                return false;
            });
            tabs.eq(2).find('button.fetch').click(function() {
                if ($(this)[0].scrollWidth == 0) {
                    var params = picker.data("params");
                    params.web_picker_dirty = true;
                    picker.data("params", params);
                } else {
                    picker.trigger("urlSelect", [tabs.eq(2).find('input.web_url').val()]);
                    picker.find("#web_infob").remove();
                }
                return false;
            });

            $('.web_url', picker).bind("focus", function () {
                $("#web_infob", picker).fadeOut('fast').queue(function () {
                    $("#web_infob", picker).remove();
                });
            });

            // ==============
            // | Public API |
            // ==============

            this.addNoovoResource = function(resource) {
                var params = picker.data("params");
                noovo_picker.addResource(resource);
                params.noovo_resources = noovo_picker.getAllResources();
                picker.data("params", params);
            };
            this.pushNoovoResource = function (resource) {
                var params = picker.data("params");
                noovo_picker.pushResource(resource);
                params.noovo_resources = noovo_picker.getAllResources();
                picker.data("params", params);
            };
            this.addMoreNoovoResources = function (resources) {
                var params = picker.data("params");
                noovo_picker.addAllResources(resources);
                params.noovo_resources = noovo_picker.getAllResources();
                picker.data("params", params);
            };

            this.addWebResource = function(resource) {
                var params = picker.data("params");
                web_picker.addResource(resource);
                params.web_resources = web_picker.getAllResources();
                picker.data("params", params);
            };
            this.pushWebResource = function(resource) {
                var params = picker.data("params");
                web_picker.pushResource(resource);
                params.web_resources = web_picker.getAllResources();
                picker.data("params", params);
            };
            this.addMoreWebResources = function (resources) {
                var params = picker.data("params");
                web_picker.addAllResources(resources);
                params.web_resources = web_picker.getAllResources();
                picker.data("params", params);
            }

            this.getAllNoovoResources = function() {
                return noovo_picker.getAllResources();
            };

            this.getNoovoSelectedResources = function() {
                return noovo_picker.getSelectedResources();
            };

            this.getAllWebResources = function() {
                return web_picker.getAllResources();
            };

            this.getWebSelectedResources = function() {
                return web_picker.getSelectedResources();
            };

            this.fetchNoovoResources = function(url, params) {

                params = params || {};
                $.getJSON(url, params, function(response) {
                    noovo_picker.removeAllResources();
                    picker.get(0).addMoreNoovoResources(response.data);
                    noovo_picker.firstPage();
                    if (loader) {
                        loader.fadeOut();
                    }
                });

                 var loader = null;
                var rf = $("input[name=resource_filter]:visible", picker);

                if (rf.length > 0) {
                    loader = $("#noovors_loader", picker);
                    if (loader.length == 0) {
                        try {
                            var rfpos = rf.position();
                            loader = $('<div class="simpleLoader" id="noovors_loader">&nbsp;</div>').insertAfter(rf).css({
                                top: rfpos["top"] + 4 + "px",
                                left: rfpos["left"] + rf.outerWidth()  + 2 + "px"
                            });
                        } catch (err) {
                            console.warn(err);
                        }
                    } else {
                        loader.show();
                    }
                }
            };

            this.webDirty = function () {
                var params = picker.data("params");
                if (params.web_picker_dirty && nav_tabs.eq(2).hasClass("active")) {
                    params.web_picker_dirty = false;
                    picker.data("params", params);
                    picker.find(".button.fetch").trigger("click");
                }
            }

            this.fetchWebResources = function(url, params, status_method, external_info_container) {
                function updateInfo(message) {
                    if (external_info_container) {
                        external_info_container.text(message)
                                               .effect("highlight", { color: "#ffff33" }, 1500);
                    } else {
                        $('<div class="infoBlock" id="web_infob">' + message + '</div>')
                            .insertAfter(web_picker)
                            .fadeIn('slow');
                    }
                }

                var add_button = picker.find("button.fetch.button").text(gettext("Loading"));
                var loader = $('#web_loader', picker);
                if (loader.length == 0) {
                    try {
                        var button_pos = add_button.position();
                        loader = $('<div class="simpleLoader" id="web_loader">&nbsp;</div>').insertAfter(add_button).css({
                            top: button_pos["top"] + 3 + "px",
                            left: button_pos["left"] + add_button.outerWidth()  + 2 + "px"
                        });
                    } catch (err) {
                        console.warn(err);
                    }
                } else {
                    loader.show();
                }
                params = params || {};

                $.getJSON(url, params, function (response) {
                    web_picker.removeAllResources();
                    var task_id = response.task_id;
                    updateWebStatus(task_id);
                });

                var updateWebStatus = function (task_id) {
                    params = {
                        method: status_method,
                        rtype: "json",
                        task_id: task_id,
                        csrfmiddlewaretoken: CSRF_TOKEN
                    };
                    $.post(url, params, function (response) {
                        if (typeof response.status == "undefined" || response.status < 0) {
                            loader.fadeOut();
                            add_button.text(gettext("Load"));
                            updateInfo(gettext("Sorry, we can't process this site."));
                            return;
                        }
                        if (response.data && response.status == 100) {
                            picker.get(0).addMoreWebResources(response.data);
                            loader.fadeOut();
                            add_button.text(gettext("Load"));
                            updateInfo((response.data.length == 0)
                                            ? gettext("Sorry, we can't find anything useful on this site.")
                                            : interpolate(ngettext("We have found one picture.",
                                                                   "We have found %s pictures",
                                                                   response.data.length), [response.data.length]));
                            web_picker.redraw();
                        }
                        if (response.status < 100) {
                            setTimeout(function() { updateWebStatus(task_id); }, 3000);
                        }
                    },
                    "json"
                );
            };
        };

            this.deselectAllNoovoResources = function() {
                noovo_picker.deselectAllResources();
            };

            this.deselectAllWebResources = function() {
                web_picker.deselectAllResources();
            };

            this.setNoovoResources = function(resources) {
                noovo_picker.removeAllResources();
                for(var i = 0; i < resources.length; i++) {
                    noovo_picker.addResource(resources[i]);
                }
            };

            this.setWebResources = function(resources) {
                web_picker.removeAllResources();
                for(var i = 0; i < resources.length; i++) {
                    web_picker.addResource(resources[i]);
                }
            };

            this.switchToTab = function(tab) {
                var params = picker.data("params");

                if(/^upload|noovo|web$/.test(tab)) {
                    nav_tabs.removeClass("active");
                    tabs.hide();
                    switch(tab) {
                        case "upload":
                            nav_tabs.eq(0).addClass("active");
                            tabs.eq(0).show();
                            picker.trigger("tabSwitch", ["upload"]);
                            break;
                        case "noovo":
                            nav_tabs.eq(1).addClass("active");
                            tabs.eq(1).show();
                            picker.trigger("tabSwitch", ["noovo"]);
                            $(noovo_picker).carousel({
                                manifest: picker.get(0).getAllNoovoResources(),
                                multiselect: params.noovo_multiselect
                            });
                            break;
                        case "web":
                            nav_tabs.eq(2).addClass("active");
                            tabs.eq(2).show();
                            picker.trigger("tabSwitch", ["web"]);
                            $(web_picker).carousel({
                                manifest: picker.get(0).getAllWebResources(),
                                multiselect: params.web_multiselect
                            });
                            break;
                    }
                }
            };

            this.setNoovoSets = function(sets) {
                var params = picker.data("params");
                noovo_sets.children().remove();
                for(var i = 0; i < sets.length; i++) {
                    if (sets[i].group) {
                      noovo_sets.append('<optgroup label="' + sets[i].name + '" />');
                    } else {
                      noovo_sets.append('<option value="' + sets[i].id + '">' + sets[i].name + '</option>');
                    }
                }
                params.noovo_sets = sets;
                picker.data("params", params);
            };

            this.lockTimeout = function() {
                var old_lock = this.noovo_picker_lock;
                this.noovo_picker_lock = true;
                return old_lock;
            };

            this.releaseTimeout = function() {
                this.noovo_picker_lock = false;
            };
        });
    };
})(jQuery);
