// Create user extension namespace
Ext.namespace('Ext.ux');
/**
 * @class Ext.ux.SwfUploadPanel
 */
Ext.ux.SwfUploadPanel = Ext.extend(Ext.grid.GridPanel, {
    strings: {
        text_add: 'Add Media',
        text_upload: 'Upload Media',
        text_cancel: 'Cancel Upload',
        text_clear: 'Clear Queue',
        text_progressbar: 'Progress Bar',
        text_remove: 'Remove File',
        text_remove_sure: 'Are you sure you wish to remove this file from queue?',
        text_error: 'Error',
        text_uploading: 'Uploading file: {0} ({1} of {2})',
        header_filename: 'Filename',
        header_size: 'Size',
        header_status: 'Status',
        status: {
            0: 'Queued',
            1: 'Uploading...',
            2: 'Completed',
            3: 'Error',
            4: 'Cancelled'
        },
        error_queue_exceeded: 'The selected file(s) exceed(s) the maximum number of {0} queued files.',
        error_queue_slots_0: 'There is no slot left',
        error_queue_slots_1: 'There is only one slot left',
        error_queue_slots_2: 'There are only {0} slots left',
        error_size_exceeded: 'The selected files size exceeds the allowed limit of {0}.',
        error_zero_byte_file: 'Zero byte file selected.',
        error_invalid_filetype: 'Invalid filetype selected.',
        error_file_not_found: 'File not found 404.',
        error_security_error: 'Security Error. Not allowed to post to different url.'
    },
    single_select: false,
    confirm_delete: true,
    file_types: "*.*",
    file_types_description: "All Files",
    file_size_limit: "200000",
    file_upload_limit: "1",
    file_queue_limit: "1",
    file_post_name: "Filedata",
    flash_url: "swfupload.swf",
    debug: false,
    autoExpandColumn: 'name',
    enableColumnResize: false,
    enableColumnMove: false,
    upload_cancelled: false,
    initComponent: function() {

        this.addEvents(
                'swfUploadLoaded',
                'fileQueued',
                'startUpload',
                'fileUploadError',
                'fileUploadSuccess',
                'fileUploadComplete',
                'allUploadsComplete',
                'removeFiles',
                'removeAllFiles',
                'fileProgress'
                );

        this.rec = Ext.data.Record.create([
            {name: 'name'},
            {name: 'size'},
            {name: 'id'},
            {name: 'type'},
            {name: 'creationdate', type: 'date', dateFormat: 'm/d/Y'},
            {name: 'status'}
        ]);

        this.rec2 = Ext.data.Record.create([
            {name: 'id'}
        ]);

        this.store = new Ext.data.Store({
            reader: new Ext.data.JsonReader({
                id: 'id'
            }, this.rec)
        });

        this.videostore = new Ext.data.Store({
            reader: new Ext.data.JsonReader({
                id: 'id'
            }, this.rec2)
        });

        this.columns = [{
            id:'name',
            header: this.strings.header_filename,
            dataIndex: 'name'
        },{
            id:'size',
            header: this.strings.header_size,
            width: 80,
            dataIndex: 'size',
            renderer: this.formatBytes
        },{
            id:'status',
            header: this.strings.header_status,
            width: 80,
            dataIndex: 'status',
            renderer: this.formatStatus.createDelegate(this)
        }];

        this.sm = new Ext.grid.RowSelectionModel({
            singleSelect: this.single_select
        });


        this.progress_bar = new Ext.ProgressBar({
            text: this.strings.text_progressbar
            //            width: this.width - 7
        });

        this.tbar = [{
            text: this.strings.text_add,
            iconCls: 'SwfUploadPanel_iconAdd',
            xhandler: function() {
                if (this.single_select) {
                    this.suo.selectFile();
                }
                else {
                    this.suo.selectFiles();
                }
            },
            xscope: this
        }, '->', {
            text: this.strings.text_cancel,
            iconCls: 'SwfUploadPanel_iconCancel',
            handler: this.stopUpload,
            scope: this,
            hidden: true
        }, {
            text: this.strings.text_upload,
            iconCls: 'SwfUploadPanel_iconUpload',
            handler: this.startUpload,
            scope: this,
            hidden: true
        }, {
            text: this.strings.text_clear,
            iconCls: 'SwfUploadPanel_iconClear',
            handler: this.removeAllFiles,
            scope: this,
            hidden: false
        }];

        this.bbar = [
            this.progress_bar
        ];

        this.addListener({
            keypress: {
                fn: function(e) {
                    if (this.confirm_delete) {
                        if(e.getKey() == e.DELETE) {
                            Ext.MessageBox.confirm(this.strings.text_remove,this.strings.text_remove_sure, function(e) {
                                if (e == 'yes') {
                                    this.removeFiles();
                                }
                            }, this);
                        }
                    } else {
                        this.removeFiles(this);
                    }
                },
                scope: this
            },
            contextmenu: function(e) {
                e.stopEvent();
            },

            render: {
                fn: function(){
                    this.resizeProgressBar();

                    this.addBtn = this.getTopToolbar().items.items[0];
                    this.cancelBtn = this.getTopToolbar().items.items[2];
                    this.uploadBtn = this.getTopToolbar().items.items[3];
                    this.clearBtn = this.getTopToolbar().items.items[4];

                    this.on('resize', this.resizeProgressBar, this);
                },
                scope: this
            }
        });


        this.on('render', function() {
            var suoID = Ext.id();
            var em = this.addBtn.el.child('em');
            em.setStyle({
                position: 'relative',
                display: 'block'
            });
            em.createChild({
                tag: 'div',
                id: suoID
            });
            this.suo = new SWFUpload({
                button_placeholder_id: suoID,
                button_width: em.getWidth(),
                button_height: em.getHeight(),
                button_cursor: SWFUpload.CURSOR.HAND,
                button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,

                upload_url: this.upload_url,
                post_params: this.post_params,
                file_post_name: this.file_post_name,
                file_size_limit: this.file_size_limit,
                file_queue_limit: this.file_queue_limit,
                file_types: this.file_types,
                file_types_description: this.file_types_description,
                file_upload_limit: this.file_upload_limit,
                flash_url: this.flash_url,

                // Event Handler Settings
                swfupload_loaded_handler: this.swfUploadLoaded.createDelegate(this),

                file_dialog_start_handler: this.fileDialogStart.createDelegate(this),
                file_queued_handler: this.fileQueue.createDelegate(this),
                file_queue_error_handler: this.fileQueueError.createDelegate(this),
                file_dialog_complete_handler: this.fileDialogComplete.createDelegate(this),

                upload_start_handler: this.uploadStart.createDelegate(this),
                upload_progress_handler: this.uploadProgress.createDelegate(this),
                upload_error_handler: this.uploadError.createDelegate(this),
                upload_success_handler: this.uploadSuccess.createDelegate(this),
                upload_complete_handler: this.uploadComplete.createDelegate(this),

                debug: this.debug,
                debug_handler: this.debugHandler
            });

            Ext.get(this.suo.movieName).setStyle({
                position: 'absolute',
                top: 0,
                left: 0
            });
        }, this);

        Ext.ux.SwfUploadPanel.superclass.initComponent.call(this);
    },
    resizeProgressBar: function() {
        this.progress_bar.setWidth(this.getBottomToolbar().el.getWidth() - 5);
        Ext.fly(this.progress_bar.el.dom.firstChild.firstChild).applyStyles("height: 16px");
    },
    debugHandler: function(line) {
        console.log(line);
    },

    formatStatus: function(status) {
        return this.strings.status[status];
    },

    formatBytes: function(size) {
        if (!size) {
            size = 0;
        }
        var suffix = ["B", "KB", "MB", "GB"];
        var result = size;
        size = parseInt(size, 10);
        result = size + " " + suffix[0];
        var loop = 0;
        while (size / 1024 > 1) {
            size = size / 1024;
            loop++;
        }
        result = Math.round(size) + " " + suffix[loop];

        return result;

        if(isNaN(bytes)) {
            return ('');
        }
        var unit, val;
        if(bytes < 999) {
            unit = 'B';
            val = (!bytes && this.progressRequestCount >= 1) ? '~' : bytes;
        } else if(bytes < 999999) {
            unit = 'kB';
            val = Math.round(bytes/1000);
        } else if(bytes < 999999999) {
            unit = 'MB';
            val = Math.round(bytes/10000) ;
            val = val/100;
        } else if(bytes < 999999999999) {
            unit = 'GB';
            val = Math.round(bytes/1000000) ;
            val = val/100;
        } else {
            unit = 'TB';
            val = Math.round(bytes/100000000000) / 10;
        }
        return (val + ' ' + unit);
    },
    swfUploadLoaded: function() {
        if(this.debug) console.info('SWFUPLOAD LOADED');

        this.fireEvent('swfUploadLoaded', this);
    },
    fileDialogStart: function() {
        if(this.debug) console.info('FILE DIALOG START');

        this.fireEvent('fileDialogStart', this);
    },
    fileQueue: function(file) {
        if(this.debug) console.info('FILE QUEUE');

        file.status = 0;
        r = new this.rec(file);
        r.id = file.id;
        this.store.add(r);
        this.fireEvent('fileQueued', this, file);
    },
    fileQueueError: function(file, code, message) {
        if(this.debug) console.info('FILE QUEUE ERROR');

        switch (code) {
            case -100:
                var slots;
                switch(message) {
                    case '0':
                        slots = this.strings.error_queue_slots_0;
                        break;
                    case '1':
                        slots = this.strings.error_queue_slots_1;
                        break;
                    default:
                        slots = String.format(this.strings.error_queue_slots_2, message);
                }
                Ext.MessageBox.alert(this.strings.text_error, String.format(this.strings.error_queue_exceeded + ' ' + slots, this.file_queue_limit));
                break;
            case -110:
                Ext.MessageBox.alert(this.strings.text_error, String.format(this.strings.error_size_exceeded, this.formatBytes(this.file_size_limit * 1024)));
                break;
            case -120:
                Ext.MessageBox.alert(this.strings.text_error, this.strings.error_zero_byte_file);
                break;
            case -130:
                Ext.MessageBox.alert(this.strings.text_error, this.strings.error_invalid_filetype);
                break;
        }
        this.fireEvent('fileQueueError', this, file, code, error);
    },
    fileDialogComplete: function(file_count) {
        if(this.debug) console.info('FILE DIALOG COMPLETE');

        if (file_count > 0) {
            this.uploadBtn.show();
        }
        this.addBtn.show();
        this.clearBtn.show();
        this.fireEvent('fileDialogComplete', this, file_count);
    },
    uploadStart: function(file) {
        if(this.debug) console.info('UPLOAD START');

        this.fireEvent('uploadStart', this, file);
        return true;
    },
    uploadProgress: function(file, bytes_completed, bytes_total) {
        if(this.debug) console.info('UPLOAD PROGRESS');

        this.store.getById(file.id).set('status', 1);
        this.store.getById(file.id).commit();
        this.progress_bar.updateProgress(bytes_completed/bytes_total, String.format(this.strings.text_uploading, file.name, this.formatBytes(bytes_completed), this.formatBytes(bytes_total)));
        this.fireEvent('uploadProgress', this, file, bytes_completed, bytes_total);
        this.fireEvent('fileProgress', this, file, bytes_completed, bytes_total);
    },
    uploadError: function(file, error, code) {
        if(this.debug) console.info('UPLOAD ERROR');

        switch (error) {
            case -200:
                Ext.MessageBox.alert(this.strings.text_error, this.strings.error_file_not_found);
                break;
            case -230:
                Ext.MessageBox.alert(this.strings.text_error, this.strings.error_security_error);
                break;
            case -290:
                this.store.getById(file.id).set('status', 4);
                this.store.getById(file.id).commit();
                break;
        }
        this.fireEvent('fileUploadError', this, file, error, code);
    },
    uploadSuccess: function(file, response) {
        if(this.debug) console.info('UPLOAD SUCCESS');

        var data = Ext.decode(response);
        if (data.success) {
            this.store.remove(this.store.getById(file.id));
            t = new this.rec2(data.videoid);
            this.videostore.add(t);
        } else {
            this.store.getById(file.id).set('status', 3);
            this.store.getById(file.id).commit();
            if (data.msg) {
                Ext.MessageBox.alert(this.strings.text_error, data.msg);
            }
        }
        this.fireEvent('fileUploadSuccess', this, file, data);
    },
    uploadComplete: function(file) {
        if(this.debug) console.info('UPLOAD COMPLETE');

        this.progress_bar.reset();
        this.progress_bar.updateText(this.strings.text_progressbar);
        if(this.suo.getStats().files_queued && !this.upload_cancelled) {
            this.suo.startUpload();
        } else {
            this.fireEvent('fileUploadComplete', this, file);
            this.allUploadsComplete();
        }
    },
    allUploadsComplete: function() {
        this.cancelBtn.hide();
        this.addBtn.show();
        this.clearBtn.show();
        this.fireEvent('allUploadsComplete', this);
    },
    addPostParam: function(name, value) {
        if (this.suo) {
            this.suo.settings.post_params[name] = value;
            this.suo.setPostParams(this.suo.settings.post_params);
        } else {
            this.post_params[name] = value;
        }
    },
    startUpload: function() {
        if(this.debug) console.info('START UPLOAD');

        this.cancelBtn.show();
        this.uploadBtn.hide();
        this.clearBtn.hide();
        this.upload_cancelled = false;
        this.fireEvent('startUpload', this);
        this.suo.startUpload();
    },
    
    stopUpload: function(file) {
        if(this.debug) console.info('STOP UPLOAD');

        this.suo.stopUpload();
        this.upload_cancelled = true;
        this.getStore().each(function() {
            if (this.data.status == 1) {
                this.set('status', 0);
                this.commit();
            }
        });
        this.cancelBtn.hide();
        if (this.suo.getStats().files_queued > 0) {
            this.uploadBtn.show();
        }
        this.addBtn.show();
        this.clearBtn.show();
        this.progress_bar.reset();
        this.progress_bar.updateText(this.strings.text_progressbar);
    },
    removeFiles: function() {
        if(this.debug) console.info('REMOVE FILES');

        var selRecords = this.getSelections();
        for (var i=0; i < selRecords.length; i++) {
            if (selRecords[i].data.status != 1) {
                this.suo.cancelUpload(selRecords[i].id);
                this.store.remove(selRecords[i]);
            }
        }
        if (this.suo.getStats().files_queued === 0) {
            this.uploadBtn.hide();
        }
        this.fireEvent('removeFiles', this);
    },
    removeAllFiles: function() {
        if(this.debug) console.info('REMOVE ALL');

        var files_left = this.suo.getStats().files_queued;
        while (files_left > 0) {
            this.suo.cancelUpload();
            files_left = this.suo.getStats().files_queued;
        }
        this.store.removeAll();
        this.cancelBtn.hide();
        this.uploadBtn.hide();
        this.fireEvent('removeAllFiles', this);
    } ,
    getVideoStore : function(){
        return this.videostore;
    }
});
