/*globals jQuery SWFUpload*/
(function($) {
    $.fn.fullUploader = function(params) {
        params = $.extend({
            upload_button_placeholder_id: "upload_placeholder",
            autostart_upload: false,
            disable_upload_button: false,
            flash_uploader_url: null,
            multi_upload: true,
            hint_message: null,
            popup_options: "channelmode=0,directories=0,fullscreen=0,height=300,width=600," +
                           "location=0,menubar=0,resizable=0,scrollbars=1,status=0," +
                           "titlebar=0,toolbar=0,left=200,top=200",
            progress_bar_image: null,
            progress_bar_image_width: 700,
            size_limit: "600MB",
            upload_parameters: {},
            upload_url: null,
            upload_popup_url: null,
            file_types: null,
            removable: true
        }, params);

        return this.each(function() {
            var uploader = $(this);
            var upload_button = $('div.left_pane>button.upload', uploader);
            var progress_bar = $('div.left_pane>div.progressBar', uploader);
            var progress_text = $('div.left_pane>div.progressText', uploader);
            var loader = $('div.left_pane>div.flash_loading', uploader);
            var start_upload_button = $('div.right_pane>button.run_queue', uploader);
            var file_list = $('div.right_pane>ul.file_list', uploader);
            var flash_uploader = null;
            var button_hint = $('<div class="upload_button_hint">'
                                + gettext("Hint: hold Ctrl, Cmd or Shift key to select multiple files.") + '</div>');

            if (params.multi_upload) {
                button_hint.insertAfter(upload_button);
            }

            // save the parameters
            uploader.data("params", params);

            button_hint.hide();
            upload_button.hide().click(function() {
                uploader[0].selectFiles();
                return false;
            });

            progress_bar.progressBar({
                image_width: params.progress_bar_image_width,
                progress_image: params.progress_bar_image
            }).hide();

            if(params.disable_upload_button) {
                start_upload_button.hide();
            } else {
                start_upload_button.click(function() {
                    uploader[0].startUpload();
                    return false;
                }).hide();
            }

            this.removeFile = function (file) {
                flash_uploader.cancelUpload(file.id);
                $('li[filename=' + file.name + ']', file_list).remove();
                if ($('li', file_list).length == 0) {
                    file_list.hide();
                    $('.uploader_hint', uploader).fadeIn();
                }
            }

            this.selectFiles = function() {
                var params = uploader.data("params");
                // Branch for Konqueror. It's a silly browser anyways.
                if($.browser.konqueror) {
                    window.open("Noovo Upload", uploader.data("params").popup_options);
                    return;
                }
                if(params.multi_upload) {
                    flash_uploader.selectFiles();
                } else {
                    flash_uploader.selectFile();
                }
            };

            this.startUpload = function() {
                if (file_list.find("li").length == 0) {
                    uploader.trigger("uploadComplete");
                }
                if(!$.browser.konqueror) {
                    upload_button.hide();
                    button_hint.hide();
                    progress_bar.show();
                    progress_text.show();
                    start_upload_button.hide();
                    flash_uploader.startUpload();
                }
            };

            this.resetUploader = function() {
                if(!$.browser.konqueror) {
                    var params = uploader.data("params");
                    params.upload_parameters.csrfmiddlewaretoken = CSRF_TOKEN;

                    flash_uploader = new SWFUpload({

                        // Uploader parameters
                        upload_url: params.upload_url,
                        post_params: params.upload_parameters,
                        flash_url: params.flash_uploader_url,
                        file_size_limit: params.size_limit,
                        use_query_string: false,
                        file_types: params.file_types,

                        // Upload button
                        button_placeholder_id: params.upload_button_placeholder_id,
                        button_text: '<span></span>',
                        button_width: "135",
                        button_height: "30",
                        button_text_left_padding: 12,
                        button_text_top_padding: 3,

                        // Custom settings
                        custom_settings: {
                            fullUploader: uploader,
                            uploadButton: upload_button,
                            uploadButtonHint: button_hint,
                            progressBar: progress_bar,
                            progressText: progress_text,
                            fileList: file_list,
                            startUploadButton: start_upload_button,
                            removable: params.removable && !params.autostart_upload
                        },

                        //
                        // Handlers
                        //
                        swfupload_loaded_handler: function() {
                            var fu = this.customSettings.fullUploader;
                            var upload_button = this.customSettings.uploadButton;
                            var upload_button_hint = this.customSettings.uploadButtonHint;
                            var progress_bar = this.customSettings.progressBar[0];
                            $('div.flash_loading', fu).fadeOut().queue(function() {
                                upload_button.fadeIn();
                                upload_button_hint.fadeIn();
                                $('.uploader_hint', fu).fadeIn();
                            });
                            progress_bar.setMaximum(100);
                            progress_bar.setValue(0);

                            // Hover effect on the underlying button
                            $(".swfupload", uploader).hover(function () {
                                upload_button.addClass("hover_x");
                            }, function () {
                                upload_button.removeClass("hover_x");
                            });
                        },
                        file_dialog_complete_handler: function(selected, queued) {
                            var progress_bar = this.customSettings.progressBar;
                            progress_bar[0].setMaximum(this.getStats().files_queued);
                            if (this.getStats().files_queued > 0) {
                                this.customSettings.startUploadButton.show();
                                if (this.customSettings.fullUploader.data("params").autostart_upload) {
                                    this.customSettings.fullUploader[0].startUpload();
                                    this.startUpload();
                                    this.customSettings.startUploadButton.hide();
                                }
                            }
                        },
                        file_queued_handler: function(file) {
                            var params = this.customSettings.fullUploader.data("params");
                            var file_list = this.customSettings.fileList;
                            var fileElem =  $('<li filename="' + file.name + '"></li>');
                            fileElem.progressBar({
                                image_width: params.progress_bar_image_width,
                                progress_image: params.progress_bar_image,
                                max: file.size,
                                text: "",
                                display_percentage: false
                            });
                            fileElem.append('<div class="filename">' + file.name + '</div>');
                            if (params.removable) {
                                var _this = this;
                                fileElem.append('<div class="removeFileIcon removelink"></div>');
                                fileElem.find(".removeFileIcon").click(function () {
                                    _this.customSettings.fullUploader[0].removeFile(file);
                                    return false;
                                });
                            }
                            fileElem.appendTo(file_list);
                            this.customSettings.fullUploader.find('.uploader_hint').hide();
                            file_list.show();
                        },
                        file_queue_error_handler: function (file, error_code, message) {
                            alert (message);
                        },
                        upload_progress_handler: function(file, bytes, total) {
                            var uploader = this.customSettings.fullUploader;
                            uploader.trigger("uploadProgress", [file, bytes, total]);
                        },
                        upload_success_handler: function(file) {
                            var uploader = this.customSettings.fullUploader;
                            uploader.trigger("uploadSuccess", [file]);
                        },
                        upload_error_handler: function(file, error_code, msg) {
                            if (error_code == SWFUpload.UPLOAD_ERROR.FILE_CANCELLED) {
                                // Ignore canceled files
                                return;
                            }
                            var uploader = this.customSettings.fullUploader;
                            this.customSettings.fileList.hide();
                            $('.uplader_hint', uploader).show();
                            uploader.trigger("uploadFailure", [file]);
                        },
                        upload_complete_handler: function(file) {
                            var progress_bar = this.customSettings.progressBar;
                            var progress_text = this.customSettings.progressText;
                            var upload_button = this.customSettings.uploadButton;
                            var upload_button_hint = this.customSettings.uploadButtonHint;
                            var file_list = this.customSettings.fileList;

                            progress_bar[0].setValue(progress_bar[0].getValue() + 1, file.name);

                            var item = file_list.find('li[filename=' + file.name + ']');

                            if (item.length) {
                                item[0].setValue(file.size);
                                item.fadeOut().queue(function() {
                                    $(this).remove();
                                });
                            }

                            if (this.getStats().files_queued) {
                                this.startUpload();
                            } else {
                                var uploader = this.customSettings.fullUploader;
                                uploader.trigger("uploadComplete");
                                progress_bar.hide();
                                progress_text.hide();
                                upload_button.fadeIn("normal");
                                upload_button_hint.fadeIn("normal");
                                $('.uploader_hint', uploader).show();
                                this.customSettings.fileList.hide();
                               // uploader[0].resetUploader();
                            }
                        }
                    });
                }
            };

            this.resetUploader();

            uploader.bind("uploadProgress", function(event, file, bytes, total) {
                file_list.find('li[filename=' + file.name + ']')[0].setValue(bytes);
            });

        });
    };
})(jQuery);