var qq = qq || {};

qq.FileUploader = function(o){
        globSelf = this;
        this._options = {
				onlyInitCore: false,
                element: null,
                action: '/server/upload',
                params: {},
                frmAction: 'upload.php',
                rmPreviosInput: true,
                allowedExtensions: [], // ex. ['jpg', 'jpeg', 'png', 'gif'] or []
                sizeLimit: 0,
				limitFiles: 10,
                onSubmit: function(id, fileName){},
                onComplete: function(id, fileName, responseJSON){},
        // UI customizations
                template:        '<div class="qq-uploader">' +
                                        '<input type="hidden" value="1" id="nextId" />' +
										'<input type="hidden" value="URL_J6CDFF13Q5" id="nextUrlId" />' +
                                        '<div class="qq-upload-button"><img class="buttons_110" src="/images/upl/browse-files.png" /></div>' +
                                        '<img class="qq-browse-url-btn buttons_70" src="/images/upl/browse-url.png" />' +
                                        '<div class="qq-upload-list" id="fileQueue"></div>' +
										'<div id="uploadactions">' +
										'<a class="qq-upload-btn" href="javascript:void(0)">Upload Files</a> | '+
										'<a class="qq-clear-queue-btn" href="javascript:void(0)">Cancel All Uploads</a>' +
										'</div>' +
                                        '<div class="qq-upload-drop-area" style="display: none;"><span>Drop files here to upload</span></div>' +
                                        '</div>',

        // template for item in file queue list
                fileTemplate:
                        '<div class="uploadifyQueueItem">' +
                        '<div class="cancel qq-upload-cancel"><a href="javascript:void(0);">' +
                        '<img border="0" src="/images/upl/cancel.png"/></a></div>' +
                        '<span class="qq-upload-file fileName"></span>&nbsp;<span class="qq-upload-size"></span>' +
                        '<span class="qq-upload-hints" style="display:none;"> - More info</span>' +
                        '<span class="percentage"/><div class="uploadifyProgress">' +
                        '<div class="uploadifyProgressBar"></div>' +
                        '</div></div>',

        classes: {
            // used to get elements from templates
            button: 'qq-upload-button',
            buttonUrl: 'qq-browse-url-btn',
            buttonUpload: 'qq-upload-btn',
            buttonClear: 'qq-clear-queue-btn',
            fieldFile: 'qq-upload-field',
            progress: 'uploadifyProgressBar',
            drop: 'qq-upload-drop-area',
            dropActive: 'qq-upload-drop-area-active',
            list: 'qq-upload-list',

            file: 'qq-upload-file',
            spinner: 'qq-upload-spinner',
            size: 'qq-upload-size',
            cancel: 'qq-upload-cancel',
                        errhint: 'qq-upload-hints',

            // added to list item when upload completes
            // used in css to hide progress spinner
            success: 'qq-upload-success',
            fail: 'qq-upload-fail'
        },

		messages: {
			serverError: "Some files have not been uploaded, please try again.",
			serverError2: "No connection to the server, please try again.",
			serverError204: "No Content",
        	serverError205:"Reset Content",
	        serverError206:"Partial Content",
	        serverError400:"Bad Request",
	        serverError401:"Authorization Required",
	        serverError403:"Forbidden",
	        serverError404:"Not Found",
	        serverError405:"Method Not Allowed",
	        serverError409:"Conflict",
	        serverError410:"Gone",
	        serverError412:"Precondition Failed",
	        serverError413:"Request Entity Too Large",
	        serverError423:"Locked",
	        serverError500:"Internal Server Error",
	        serverError501:"Not Implemented",
	        serverError502:"Bad Gateway",
	        serverError503:"Service Unavailable",
	        serverError504:"Gateway Timeout",	
			typeError: "File [{file}] has invalid extension. Only {extensions} are allowed.",
			sizeError: "File [{file}] is too large. The maximum file size is {sizeLimit}.",
			filelimitError: "There are too many files in the queue.<br>The maximum number of files is {limitFiles}.",
			emptyError: "File [{file}] is empty.",
			samefileError: "File [{file}] is already in the list.",
			notUrlError: "File [{file}]<br> was not found on the remote server.",
			emptyUrlError: "Please enter a correct URL.",
			UrlError: "The URL is incorrect!<br>[{file}]<br>Please enter a correct URL."
		},
        showMessage: function(message, title, back){
                        if ( !title ) title = "Upload Error";
            $.showError(title, message, back);
        },
                isAttachedEventsBtns: false,
                nextId: 0
    };

        qq._isCanUploadList = false;
        qq._fileBuff = {};
    qq.extend(this._options, o);

    this._element = this._options.element;

    if (this._element.nodeType != 1){
        throw new Error('element param of FileUploader should be dom node');
    }

    if (!this._options.onlyInitCore) this._element.innerHTML = this._options.template;

    // number of files being uploaded
    this._filesInProgress = 0;

    // easier access
    this._classes = this._options.classes;

    if (!this._options.onlyInitCore) this._handler = this._createUploadHandler();

    if (!this._options.onlyInitCore) this._bindCancelEvent();

    var self = this;
	if (!this._options.onlyInitCore) {
	    this._button = new qq.UploadButton({
	        element: this._getElement('button'),
	        multiple: qq.UploadHandlerXhr.isSupported(),
            frmAction: this._options.frmAction,
            rmPreviosInput: this._options.rmPreviosInput,
			onChange: function(input){
            	self._onInputChange(input);
	        }
	    });
	}

    var uploadUrl = this._getElement('buttonUrl');
    qq.attach(uploadUrl, 'click', function(e) {
        qq.showPromptURL(e);
    });

    if (!this._options.onlyInitCore) this._setupDragDrop();
};

qq.FileUploader.prototype = {
    setParams: function(params){
        this._options.params = params;
    },
    /**
     * Returns true if some files are being uploaded, false otherwise
     */
    isUploading: function(){
        return !!this._filesInProgress;
    },
    /**
     * Gets one of the elements listed in this._options.classes
     *
     * First optional element is root for search,
     * this._element is default value.
     *
     * Usage
     *  1. this._getElement('button');
     *  2. this._getElement(item, 'file');
     **/
    _getElement: function(parent, type){
        if (typeof parent == 'string'){
            // parent was not passed
            type = parent;
            parent = this._element;
        }

        var element = qq.getByClass(parent, this._options.classes[type])[0];

        if (!element){
            throw new Error('element not found ' + type);
        }

        return element;
    },
    _error: function(code, fileName, title, back){
        var message = this._options.messages[code];
        message = message.replace('{file}', this._formatFileName(fileName));
        message = message.replace('{extensions}', this._options.allowedExtensions.join(', '));
		message = message.replace('{limitFiles}', this._options.limitFiles);
        message = message.replace('{sizeLimit}', this._formatSize(this._options.sizeLimit));
        this._options.showMessage(message, title, back);
    },
    _formatFileName: function(name){
        if (name.length > 33){
            name = name.slice(0, 19) + '...' + name.slice(-13);
        }
        return name;
    },
    _isAllowedExtension: function(fileName){
        var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
        var allowed = this._options.allowedExtensions;

        if (!allowed.length){return true;}

        for (var i=0; i<allowed.length; i++){
            if (allowed[i].toLowerCase() == ext){
                return true;
            }
        }

        return false;
    },
        _addHistoryFileName: function(fileName, id, size, ifUrl){
                var self = this;
                qq.addHistoryFileName(self, fileName, id, size, ifUrl);
        },
        _removeFromHistory: function(id, fromHistory){
                qq.removeFromHistory(id, fromHistory);
        },
        _setupDragDrop: function(){
        function isValidDrag(e){
            var dt = e.dataTransfer,
                // do not check dt.types.contains in webkit, because it crashes safari 4
                isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;

            // dt.effectAllowed is none in Safari 5
            // dt.types.contains check is for firefox
            return dt && dt.effectAllowed != 'none' &&
                (dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files')));
        }

        var self = this, dropArea = this._getElement('drop');

        dropArea.style.display = 'none';

        var hideTimeout;
        qq.attach($("div.upContainer").get(0), 'dragenter', function(e){
            e.preventDefault();
        });

		qq.attach($("div.upContainer").get(0), 'dragout', function(e){dropArea.style.display = 'none';});
		qq.attach($("div.upContainer").get(0), 'mouseout', function(e){dropArea.style.display = 'none';});
		qq.attach(document, 'mouseup', function(e){setTimeout(function(){dropArea.style.display = 'none';}, 300);});

        qq.attach($("div.upContainer").get(0), 'dragover', function(e){
            if (isValidDrag(e)){
				var highDrop = $(".qq-uploader").height();
				$(dropArea).height(highDrop);
				dropArea.style.display = 'block';
                if (hideTimeout){
                    clearTimeout(hideTimeout);
                }

                if (dropArea == e.target || qq.contains(dropArea,e.target)){
                    var effect = e.dataTransfer.effectAllowed;
                    if (effect == 'move' || effect == 'linkMove'){
                        e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
                    } else {
                        e.dataTransfer.dropEffect = 'copy'; // for Chrome
                    }
                    qq.addClass(dropArea, self._classes.dropActive);
                    e.stopPropagation();
                } else {
                    dropArea.style.display = 'block';
                    e.dataTransfer.dropEffect = 'none';
                }

                e.preventDefault();
            }
        });

        qq.attach($("div.upContainer").get(0), 'dragleave', function(e){
            if (isValidDrag(e)){

                if (dropArea == e.target || qq.contains(dropArea,e.target)){
                    qq.removeClass(dropArea, self._classes.dropActive);
                    e.stopPropagation();
                } else {

                    if (hideTimeout){
                        clearTimeout(hideTimeout);
                    }

                    hideTimeout = setTimeout(function(){
                        dropArea.style.display = 'none';
                    }, 77);
                }
            }
        });

        qq.attach(dropArea, 'drop', function(e){
            dropArea.style.display = 'none';
            self._uploadFileList(e.dataTransfer.files);
            e.preventDefault();
        });
    },
    _createUploadHandler: function(){
        var self = this,
            handlerClass;

        if ( qq.UploadHandlerXhr.isSupported() ) {
            handlerClass = 'UploadHandlerXhr';
			globSelf.handlerClass = 'UploadHandlerXhr';
        } else {
            handlerClass = 'UploadHandlerForm';
			globSelf.handlerClass = 'UploadHandlerForm';
        }

        var handler = new qq[handlerClass]({
            action: this._options.action,
            onProgress: function(id, fileName, loaded, total, SaveXhr, anime){
                // is only called for xhr upload
                self._updateProgress(id, loaded, total, SaveXhr, anime);
            },
            onComplete: function(id, fileName, result, SaveXhr){
                self._filesInProgress--;
                                if ( SaveXhr )
                                {
                                        qq.onCompleteServe('{"success":true,"id":"'+(id + 1)+'"}');
                                }

                //var item = self._getItemByFileId(id);
                                //item.id = id + 1;
                //qq.remove(self._getElement(item, 'cancel'));
                //qq.remove(self._getElement(item, 'spinner'));
               /*
                if (result.success){
                    qq.addClass(item, self._classes.success);
                } else {
                    qq.addClass(item, self._classes.fail);

                    if (result.error){
                       self._options.showMessage(result.error);
                    }
                }
               */
               // self._options.onComplete(id, fileName, result);
            }
        });

        return handler;
    },
    _onInputChange: function(input){
		var preRes = true;
        if (this._handler instanceof qq.UploadHandlerXhr){
            preRes = this._uploadFileList(input.files, input);
            if ( $.browser.chrome || $.browser.safari || ( $.browser.chrome && $.browser.safari ) ) {
               return;
			}
        } else {
            if (this._validateFile(input)){
                this._uploadFile(input);
            }
        }

		var cVer = $.browser.codeversion.replace(/\./g, '');
		cVer = cVer.substr(0, 2);
        if ( preRes && cVer < 36 ) this._button.reset();
    },
    _uploadFileList: function(files, input){
        var valid = true;

        var i = files.length;
        while (i--){
            if (!this._validateFile(files[i])){
                valid = false;
                //break;
            }
			else
			{
				this._uploadFile(files[i]);
			}
        }
		//$.log(globSelf.handlerClass);
		var cVer = $.browser.codeversion.replace(/\./g, '');
        cVer = cVer.substr(0, 2);
		if ( ( $.browser.firefox && cVer >= 36 ) || $.browser.chrome || $.browser.safari || ( $.browser.chrome && $.browser.safari ) ) {
			setTimeout(function(){$(input).val("");}, 100);
		}
/*
        if (!valid) return false;
        if (valid)
		{
            var i = files.length;
            while (i--)
			{
				this._uploadFile(files[i]);
				//if ( $.browser.chrome || $.browser.safari || ( $.browser.chrome && $.browser.safari ) )
				//{
					//document.getElementById("nextId").value++;
					//qq._getNextFileId();
				//}
			}
        }
*/
        return true;
    },
    _uploadFile: function(fileContainer){
        var id = this._handler.add(fileContainer);
        var name = this._handler.getName(id);
        //this._options.onSubmit(id, name);
        this._addToList(id, name);
        this._handler.upload(id, this._options.params);
    },
    _validateFile: function(file){
        var name,size;

		if ( typeof(filesNum) != "undefined" ) {
			if ( filesNum > 0 ){
				backToUpload();
			}
		}

        if (file.value){
            // it is a file input
            // get input value and remove path to normalize
            name = file.value.replace(/.*(\/|\\)/, "");
        } else {
            // fix missing properties in Safari
            name = file.fileName != null ? file.fileName : file.name;
            size = file.fileSize != null ? file.fileSize : file.size;
        }

		if ( qq._count(qq._fileBuff) >= this._options.limitFiles ){
			this._error('filelimitError', name);
			return false;
		} else if (! this._isAllowedExtension(name)){
            this._error('typeError',name);
            return false;
        } else if (size === 0){
            this._error('emptyError',name);
            return false;
        } else if (size && this._options.sizeLimit && size > this._options.sizeLimit){
            this._error('sizeError',name);
            return false;
        } else if (this._isPresentInList(name)){
			this._error('samefileError',name);
			return false;
		}

                //var idx = document.getElementById("nextId").value;
				var idx = qq._getNextFileId();
                this._addHistoryFileName(name, idx, size);
                if (!this._options.isAttachedEventsBtns) this._attachBtnsEvents();

        return true;
    },
        _attachBtnsEvents: function(){
                var self = this;
                var uploadBtn = this._getElement('buttonUpload');
                var clearBtn = this._getElement('buttonClear');

                qq.attach(uploadBtn, 'click', function(e) {
						if ( globSelf.dirIsSet == '1' ) {
	                        self._startUploadByQueue(e);
						} else {
							globSelf.dirIsSet = 1;
							folder = randomString();
							$("#folder").val(folder);
							$.ajax({url: '/setdir.html',type: 'POST', data: 'folder='+folder});	
							setTimeout(function(){self._startUploadByQueue(e);}, 80);
						}
                });

                qq.attach(clearBtn, 'click', function(e) {
						globSelf.dirIsSet = '';
                        self._clearQueueUpload(e);
                });

                this._options.isAttachedEventsBtns = true;

        },
        _startUploadByQueue: function(e){
			var self = this;
			if ( typeof $("#fileQueue div.uploadifyQueueItem[_x_inprocess='yes']").attr("id") != "undefined" ) {
				setTimeout(function(){globSelf._startUploadByQueue();}, 400);
				return;
			}
			if ( !globSelf._isCanUploadList ) return;
			if ( 0 == qq._count(qq._fileBuff) || "0" == qq._count(qq._fileBuff) || !qq._count(qq._fileBuff) ) {
				globSelf.submitQueue = false;
				globSelf._isCanUploadList = true;
				return;
			}
			if ( !globSelf.submitQueue || typeof(globSelf.submitQueue) == 'undefined' )
			{
				//$.each(qq._fileBuff,
				$("#fileQueue div.uploadifyQueueItem").each(
					function(num, elm){
					//function(idx, data){
						if ( $(this).attr("_x_inprocess") == "yes" ) return;
						//if ( !globSelf._isCanUploadList ) return;
						var itemID = $(this).attr("id");
						var idx = parseInt(itemID) ? itemID : itemID;
						var data = qq._fileBuff[itemID];
						if ( typeof data == 'undefined' ) return;
						
						if ( data.submit ) return;
						if ( globSelf.submitQueue ) return;
						if ( idx == globSelf.submitedID ) return;
						if ( data.name )
						{
							$(this).attr("_x_inprocess", "yes");
							if ( !data.remotefile || data.remotefile == 'false' )
							{
								var cVer = $.browser.codeversion.replace(/\./g, '');
								cVer = cVer.substr(0, 2);
								if ( ( $.browser.firefox && cVer >= 36 ) || $.browser.chrome || $.browser.safari || ( $.browser.chrome && $.browser.safari ) )
								{
									self._handler.upload(idx - 1, self._options.params, true);
								}
								else
								{
									if ( !qq.UploadHandlerXhr.isSupported() )
									{
										var fID  = '<input type="hidden" name="elemID" value="'+idx+'" />';
											fID += '<input type="hidden" name="UPLOAD_IDENTIFIER" value="'+qq.getRand()+'"/>"';
										fID = $(fID);
										$("form[name='qqform_frame_"+idx+"']")
											.append(fID)
											.submit();
									}
									else
									{
										if ( $.browser.msie || $.browser.opera || ( $.browser.firefox && cVer < 36 ) )
										{
											$("form[name='form_frame_"+idx+"']").submit();
										}
									}
									qq.startCheckProgress(idx);
								}
							}
							else
							{
								if ( data.remotefile )
								{
									qq.startUploadURLFile(idx);
                                }
                            }
                            if ( typeof data != 'undefined' )
							{
								data.submit = 1;
								data.submited = 0;
							}
							globSelf.submitedID = idx;
							globSelf.submitQueue = true;
						}
					}
				);
			}
        },
        _removeFileFromQueue: function(elem, idx, hist){
                qq.removeFileFromQueue(elem, idx, hist);
        },
        _clearQueueUpload: function(e){
			var self = this;
			$(".uploadifyQueueItem").each(
				function(idx, elm) {
					$(this).fadeOut(200, function(){$(this).remove();});
				}
			);

			$(".qq-upload-button form[name*='form_frame_']").each(
				function(idx, elm) {
					if ( qq._count(qq._fileBuff) || qq._count(qq._fileBuff) != "0" ) { 
						var fileName = $.trim($("input[name='file']", this).val());
						if ( "" != fileName )
						{
							var cntForms = eval(($(".qq-upload-button").get(0).getElementsByTagName('form')).length);
							if ( cntForms > 1 && !$.browser.msie && !$.browser.opera && !$.browser.chrome && !$.browser.safari )
							{
								var frameName = $(this).attr('target');
								$(this).remove();
								$("iframe[name='"+frameName+"']").remove();
							}
							//self._handler.cancel(idx - 1);
							//self._handler.cancel(idx + 1);
							//self._removeFromHistory(idx + 1, true);
						}
					}
				}
			);

            for ( key in qq._fileBuff )
            {
				self._handler.cancel(key, "qq.removeFromHistory");
				if ( globSelf.handlerClass == 'UploadHandlerXhr' ) {
					//self._removeFromHistory(key, true);
					self._handler.cancel(key, "qq.removeFromHistory");
				} else {
					self._handler.cancel(key);
					self._removeFromHistory(key);
				}
                delete qq._fileBuff[key];
			}

			if ( !qq._count(qq._fileBuff) && uploadType == 'FAKE' ) {
				self._button._createInput();
				qq._fileBuff = {};
			}
			globSelf.submitQueue = false;
			globSelf._isCanUploadList = true;
        },
        _isPresentInList: function(fileName){
                for ( key in qq._fileBuff ){
                        if ( qq._fileBuff[key].name == fileName ) return true;
                }
                return false;
        },
    _addToList: function(id, fileName){
		var self = this;
        var item = qq.toElement(this._options.fileTemplate);
        item.qqFileId = id;
        //var prevID = document.getElementById("nextId").value;
		//var prevID = qq._getNextFileId(true) - 1;
		var prevID = 0;
		if ( id >= 0 || parseInt(id) ) prevID = id + 1;
		else prevID = parseInt(id.replace("qq-upload-handler-iframe", "")) + 1;
		item.id = prevID;

        var fileElement = this._getElement(item, 'file');
        qq.setText(fileElement, this._formatFileName(fileName));
        //this._getElement(item, 'size').style.display = 'none';
                this._getElement(item, 'size').innerHTML = '<img class="loading" src="/images/upl/loading.gif" />';
                qq.attach(this._getElement(item, 'cancel'), 'click', function(e){
                        e = e || window.event;
                        var target = e.target || e.srcElement;
                        if ( $(target).parent().parent().hasClass(self._classes.cancel) )
                        {
                                qq.preventDefault(e);
								var idx = $(target).parent().parent().parent().attr("id");
                                self._handler.cancel(idx);
                                $(item).fadeOut(200);
                                self._removeFileFromQueue(target, idx, true);
                        }
                });

        this._getElement('list').appendChild(item);
        this._filesInProgress++;
    },
    _updateProgress: function(id, loaded, total, SaveXhr, anime){
                if ( loaded >= total )
                {
                        var item = this._getItemByFileId(id);
                        var size = this._getElement(item, 'size');
                var text = this._formatSize(total);
                if ( !SaveXhr ) qq.setText(size, '('+text+')');
                }
        if ( SaveXhr ) qq.setProgressBar(id + 1, loaded, total, '', anime);
    },
    _formatSize: function(bytes){
        var i = -1;
        do {
            bytes = bytes / 1024;
            i++;
        } while (bytes > 1024);

        return Math.max(bytes, 0.1).toFixed(2) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
    },
    _getItemByFileId: function(id){
        var item = this._getElement('list').firstChild;

        // there can't be text nodes in our dynamically created list
        // because of that we can safely use nextSibling
        while (item){
            if (item.qqFileId == id){
                return item;
            }

            item = item.nextSibling;
        }
    },
    /**
     * delegate click event for cancel link
     **/
    _bindCancelEvent: function(){
        var self = this,
            list = this._getElement('list');

        qq.attach(list, 'click', function(e){
            e = e || window.event;
            var target = e.target || e.srcElement;

            if (qq.hasClass(target, self._classes.cancel)){
                qq.preventDefault(e);

                var item = target.parentNode;
                self._handler.cancel(item.qqFileId);
                qq.remove(item);
            }
        });

    },
    _getIframeContentJSON: function(iframe){
        // iframe.contentWindow.document - for IE<7
        var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
            response;

        try{
            response = eval("(" + doc.body.innerHTML + ")");
        } catch(err){
            response = {};
        }

        return response;
    }
};

qq.UploadButton = function(o){
    this._options = {
        element: null,
        // if set to true adds multiple attribute to file input
        multiple: false,
        // name attribute of file input
        name: 'file',
                frmName: 'uForm',
                frmAction: 'upload.php',
                rmPreviosInput: true,
        onChange: function(input){},
        hoverClass: 'qq-upload-button-hover',
        focusClass: 'qq-upload-button-focus'
    };

    qq.extend(this._options, o);

    this._element = this._options.element;

    // make button suitable container for input
    qq.css(this._element, {
        position: 'relative',
        overflow: 'hidden',
        // Make sure browse button is in the right side
        // in Internet Explorer
        direction: 'ltr'
    });

    this._input = this._createInput();
};

qq.UploadButton.prototype = {
    /* returns file input element */
    getInput: function(){
        return this._input;
    },
    /* cleans/recreates the file input */
    reset: function(){
        qq.removeClass(this._element, this._options.focusClass);
        this._input = this._createInput();
    },
    _createInput: function(){
        var self = this;
		var ID = qq._getNextFileId(true);
        var input = document.createElement("input");
        var uplIdent = document.createElement("input");
        var params = "";

        if ( !$.browser.msie && !$.browser.opera )
        {
                        var fID = document.createElement("input");
                        var iframe = this._createIframe(ID);
                        var form = this._createForm(iframe, params);
        }

        if (this._options.multiple){
            input.setAttribute("multiple", "multiple");
        }

                qq.addClass(input, 'qq-upload-field');
        input.setAttribute("type", "file");
        input.setAttribute("name", this._options.name);

        qq.css(input, {
            position: 'absolute',
            right: 0,
            top: 0,
            zIndex: 1,
            fontSize: '2em',
            margin: 0,
            padding: 0,
            cursor: 'pointer',
            opacity: 0
        });

                if ( !$.browser.msie && !$.browser.opera )
                {
                        form.appendChild(input);

                        fID.setAttribute("type", "hidden");
                        fID.setAttribute("name", "elemID");
                        fID.value = ID;
                        form.appendChild(fID);
                        uplIdent.setAttribute("type", "hidden");
                        uplIdent.setAttribute("name", "UPLOAD_IDENTIFIER");
                        uplIdent.value = qq.getRand();
                        form.appendChild(uplIdent);
                        this._element.appendChild(form);
                        this._element.appendChild(iframe);
                }
                else
                {
                        this._element.appendChild(input);
                }

        qq.attach(input, 'change', function(){
            self._options.onChange(input);
			if ( !$.browser.msie && !$.browser.opera && !$.browser.firefox ) {
				self.reset();
			}
        });
	
		return input;
    },
    _createIframe: function(id){
        // We can't use following code as the name attribute
        // won't be properly registered in IE6, and new window
        // on form submit will open
        // var iframe = document.createElement('iframe');
        // iframe.setAttribute('name', id);

        var iframe = qq.toElement('<iframe src="javascript:\'\';" name="frame_' + id + '"> </iframe>');
        // src="javascript:false;" removes ie6 prompt on https

        iframe.setAttribute('id', 'frame_'+id);

        iframe.style.display = 'none';
        document.body.appendChild(iframe);

        return iframe;
    },
    /**
     * Creates form, that will be submitted to iframe
     */
    _createForm: function(iframe, params){
		if ( isMob == 'true' ) {
			$("img.buttons_110").remove();
        	var form = qq.toElement('<form method="post" enctype="multipart/form-data" style="display:none;visibility:hidden;"> </form>');
		} else {
			var form = qq.toElement('<form method="post" enctype="multipart/form-data"> </form>');
		}

        var queryString = '?';
        for (var key in params){
            queryString += '&' + key + '=' + encodeURIComponent(params[key]);
        }

		queryString += '&x='+qq.getRand();

        form.setAttribute('action', this._options.frmAction + queryString);
        form.setAttribute('target', iframe.name);
                form.setAttribute('name', 'form_'+iframe.id );

        return form;
    }
};

qq.UploadHandlerForm = function(o){
    this._options = {
        action: '/upload',
        onComplete: function(id, fileName, response){}
    };
    qq.extend(this._options, o);

    this._inputs = {};
};
qq.UploadHandlerForm.prototype = {
    add: function(fileInput){
        fileInput.setAttribute('name', 'qqfile');
        var id = 'qq-upload-handler-iframe' + qq.getUniqueId();

        this._inputs[id] = fileInput;

        if (fileInput.parentNode){
            //qq.remove(fileInput);
        }
        return id;
    },
    upload: function(id, params){
        var input = this._inputs[id];
		var fID = parseInt(id.replace("qq-upload-handler-iframe", "")) + 1;

        if (!input){
            throw new Error('file with passed id was not added, or already uploaded or cancelled');
        }

        var fileName = this.getName(id);
		//$.log(fileName);

        var iframe = this._createIframe(id);
        var form = this._createForm(iframe, params);
        form.appendChild(input);

        var self = this;
        this._attachLoadEvent(iframe, function(){
            var res = self._getIframeContentJSON(iframe);
                        if ( !res ) qq.onCompleteServe('{"id":"'+$(iframe).attr('id')+'"}');
                        if ( res.id )
                        {
                                var size = qq._fileBuff[res.id]['size'];
                                $("div#"+res.id+" span.qq-upload-size").text("("+qq.formatSize(size)+")");
                                qq.onCompleteServe(res);
                        }
                        else
                        {
                                $("div#"+fID+" span.qq-upload-size").text("("+qq.formatSize(res.size)+")");
                                qq._fileBuff[fID]['size'] = res.size;
                                qq._unlockQueue();
                        }
        });

        if ( !qq._fileBuff[fID]['submited'] )
                {
                        qq._lockQueue();
                        form.submit();
                        qq._fileBuff[fID]['submited'] = 1;
                }

        return id;
    },
    cancel: function(id){
        var iframe = document.getElementById("qq-upload-handler-iframe"+(id - 1));
        if (iframe)
        {
            iframe.setAttribute('src', "javascript:'';");
			$("#qq-upload-handler-iframe"+(id - 1)).remove();
			$("form[name='qqform_frame_"+id+"']").remove();
        }
    },
    getName: function(id){
        return this._inputs[id].value.replace(/.*(\/|\\)/, "");
    },
    getSize: function(id){
        var file = this._inputs[id];
        return file.fileSize != null ? file.fileSize : file.size;
    },
    _attachLoadEvent: function(iframe, callback){
        qq.attach(iframe, 'load', function(){
            if (!iframe.parentNode){
                return;
            }

            // fixing Opera 10.53
            if (iframe.contentDocument &&
                iframe.contentDocument.body &&
                iframe.contentDocument.body.innerHTML == "false"){
                return;
            }

            callback();
        });
    },
    _getIframeContentJSON: function(iframe){
        var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
            response;

        try{
            response = eval("(" + doc.body.innerHTML + ")");
        } catch(err){
            response = {};
        }
        return response;
    },
    _createIframe: function(id){
		var sID = qq._getNextFileId(true) - 1;
        var iframe = qq.toElement('<iframe src="javascript:\'\';" id="'+sID+'" name="'+id+'" />');

        iframe.setAttribute('id', id);

        iframe.style.display = 'none';
        document.body.appendChild(iframe);

        return iframe;
    },
    _createForm: function(iframe, params){
		var sID = qq._getNextFileId(true) -1;
        var form = qq.toElement('<form method="post" enctype="multipart/form-data"></form>');

        var queryString = '?';
        for (var key in params){
            queryString += '&' + key + '=' + encodeURIComponent(params[key]);
        }

		queryString += '&x='+qq.getRand();

        form.setAttribute('name', 'qqform_frame_'+sID);
        form.setAttribute('action', this._options.action + queryString);
        form.setAttribute('target', iframe.name);
        form.style.display = 'none';
        document.body.appendChild(form);

        return form;
    }
};

qq.UploadHandlerXhr = function(o){
    this._options = {
        action: '/upload',
        onProgress: function(id, fileName, loaded, total, SaveXhr){},
        onComplete: function(id, fileName, response, forseSave){}
    };
    qq.extend(this._options, o);

    this._files = [];
    this._xhrs = [];
};

// static method
qq.UploadHandlerXhr.isSupported = function(){
    return typeof File != "undefined" &&
        typeof (new XMLHttpRequest()).upload != "undefined";
};

qq.UploadHandlerXhr.prototype = {
    /**
     * Adds file to the queue
     * Returns id to use with upload, cancel
     **/
    add: function(file){
		var ID = this._files.push(file);
        return ID - 1;
    },
    /**
     * Sends the file identified by id and additional query params to the server
     * @param {Object} params name-value string pairs
     */
    upload: function(id, params, forseSave){
        var file = this._files[id],
            name = this.getName(id),
            size = this.getSize(id);
		if ( typeof file.name == 'undefined' ) file.name = name;
		if ( typeof file.size == 'undefined' ) file.size = size;
		if ( typeof file.mozFullPath == 'undefined' ) file.mozFullPath = "";

        if (!file){
            throw new Error('file with passed id was not added, or already uploaded or cancelled');
        }

        var xhr = this._xhrs[id] = new XMLHttpRequest();
        var self = this;

		xhr.upload.addEventListener('progress', function(event) {
			//$.log("loaded:"+event.loaded+", total:"+ event.total);
			if (event.lengthComputable) {
				var SaveXhr = false;
				if ( forseSave ) SaveXhr = true;
				var loaded = event.loaded;
				var total = event.total;
				var globLoaded = 0;
				//$.log("loaded:"+event.loaded+", total:"+ event.total);
				if ( typeof(qq._fileBuff[(id + 1)]) != 'undefined' && typeof(qq._fileBuff[(id + 1)]['loaded']) == 'undefined' ) {
					//loaded = total - 100;
					//$.log(total+" - "+loaded)
					qq._fileBuff[(id + 1)]['loaded'] = loaded;
					if ( loaded > parseInt(total / 2) ) {
						globSelf.isSOKS = true;
						self._options.onProgress(id, name, loaded, total, SaveXhr, true);
					} else {
						self._options.onProgress(id, name, loaded, total, SaveXhr);
					}	
				} else {
					if ( typeof(qq._fileBuff[(id + 1)]) != 'undefined' && typeof(qq._fileBuff[(id + 1)]['loaded']) != 'undefined' ) {
						globLoaded = qq._fileBuff[(id + 1)]['loaded'];
						if ( globSelf.isSOKS || globLoaded > parseInt(total / 2) ) {
							globSelf.isSOKS = true;
	                        self._options.onProgress(id, name, loaded, total, SaveXhr, true);
	                    } else {
	                        self._options.onProgress(id, name, loaded, total, SaveXhr);
	                    }
					}
				}

/*
				var globLoaded = 0;
				var globIter = 0;
				var half = 0; //parseInt(total / 2);
				var part4 = 0; //parseInt(total / 4);
				if ( typeof(qq._fileBuff[(id + 1)]) != 'undefined' && typeof(qq._fileBuff[(id + 1)]['loaded']) != 'undefined' ) {
					globLoaded = qq._fileBuff[(id + 1)]['loaded'];
					globIter = qq._fileBuff[(id + 1)]['iter'];
					qq._fileBuff[(id + 1)]['loaded'] = loaded;
					qq._fileBuff[(id + 1)]['iter'] = parseInt(total / 2) + parseInt(globLoaded / 2);
				} else {
					qq._fileBuff[(id + 1)]['loaded'] = loaded;
					qq._fileBuff[(id + 1)]['iter'] = parseInt(total / 2) + parseInt(loaded / 2);
				}

				if ( globLoaded < loaded ) { //&& loaded < globIter ) {
					self._options.onProgress(id, name, loaded, total, SaveXhr);
				} else {
					self._options.onProgress(id, name, loaded, total, SaveXhr, true);
				}
*/
/*
				if ( loaded < half || loaded < part4 ) {
					self._options.onProgress(id, name, loaded, total, SaveXhr);
				} else {
					self._options.onProgress(id, name, loaded, total, SaveXhr, true);		
				}
*/
			}
		}, false);


/*
        xhr.upload.onprogress = function(e){
			$.log("loaded:"+e.loaded+", total:"+ e.total);
            if (e.lengthComputable){
                var SaveXhr = false;
                if ( forseSave ) SaveXhr = true;
                self._options.onProgress(id, name, e.loaded, e.total, SaveXhr);
            }
        };
*/

        xhr.onreadystatechange = function(){
            // the request was aborted/cancelled
            if (!self._files[id]){
                return;
            }

            if (xhr.readyState == 4){
				var response = {};
                self._options.onProgress(id, name, size, size);
				if (forseSave && (!xhr.status || xhr.status == '0' || !$.trim(xhr.responseText)) ) {
					response = '{"id":'+(id + 1)+', "error":"'+globSelf._options.messages.serverError2+'"}';
					qq.onCompleteServe(response);
					self._files[id] = null;
					self._xhrs[id] = null;
					qq._unlockQueue();
					return;
				}
				if (xhr.status != 200){
					try{
						var errCode = parseInt(xhr.status);
						if ( typeof globSelf._options.messages['serverError'+errCode] != "undefined" ) {
							response = '{"id":'+(id + 1)+', "error":"'+globSelf._options.messages['serverError'+errCode]+'"}';
						} else {
							response = '{"id":'+(id + 1)+', "error":"'+globSelf._options.messages.serverError+'"}';
						}
						qq.onCompleteServe(response);
						self._files[id] = null;
						self._xhrs[id] = null;
						qq._unlockQueue();
					} catch(e) {}
					return;
				}
                if (xhr.status == 200){
                    try {
                        response = eval("(" + xhr.responseText + ")");
                    } catch(err){
                    }

                    if ( forseSave ) self._options.onComplete(id, name, response, forseSave);

                } else {
                    if ( forseSave ) self._options.onComplete(id, name, response, forseSave);
                }
                if ( forseSave )
				{
					self._files[id] = null;
    	            self._xhrs[id] = null;
				}
                qq._unlockQueue();
            }
        };

        // build query string
        var queryString  = '?fileID='+(id + 1);
			queryString += '&qqfile='+encodeURIComponent(name);
			queryString += '&summ='+qq._fileBuff[(id + 1)].summ;
			queryString += '&size='+size;
		if ( forseSave ) queryString += '&save=SaveXhr';

        for (var key in params){
            queryString += '&' + key + '=' + encodeURIComponent(params[key]);
        }

		queryString += '&x='+qq.getRand();

        xhr.open("POST", this._options.action + queryString, true);
		xhr.setRequestHeader("Cache-Control", "no-cache");
		xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
		xhr.setRequestHeader("X-File-Name", file.name);
		if ( forseSave ) xhr.setRequestHeader("Content-Type", "text/plain");

        if ( forseSave ) xhr.send(file);
        else xhr.send(null);
    },
    cancel: function(id, func){
		var preID = id;
		id = id - 1;
        this._files[id] = null;

        if (this._xhrs[id]){
            this._xhrs[id].abort();
            this._xhrs[id] = null;
        }
		if ( func ) {
			//$.log("Run callback for remove from history on server");
			eval ( func+"("+preID+", true);" );
		}
    },
    getName: function(id){
        // fix missing name in Safari 4
        var file = this._files[id];
		if (typeof(file)=="undefined" || file == null) return;
        return (file.fileName) ? file.fileName : file.name;
    },
    getSize: function(id){
        // fix missing size in Safari 4
        var file = this._files[id];
		if (typeof(file)=="undefined" || file == null) return;
        return file.fileSize != null ? file.fileSize : file.size;
    }
};

//var qq = qq || {};

/**
 * Adds all missing properties from obj2 to obj1
 */
qq.extend = function(obj1, obj2){
    for (var prop in obj2){
        obj1[prop] = obj2[prop];
    }
};

/**
 * @return {Number} unique id
 */
qq.getUniqueId = (function(){
    var id = 0;
    return function(){
        return id++;
    };
})();

//
// Events

qq.attach = function(element, type, fn){
    if (element.addEventListener){
        element.addEventListener(type, fn, false);
    } else if (element.attachEvent){
        element.attachEvent('on' + type, fn);
    }
};
qq.detach = function(element, type, fn){
    if (element.removeEventListener){
        element.removeEventListener(type, fn, false);
    } else if (element.attachEvent){
        element.detachEvent('on' + type, fn);
    }
};

qq.preventDefault = function(e){
    if (e.preventDefault){
        e.preventDefault();
    } else{
        e.returnValue = false;
    }
};
//
// Node manipulations

/**
 * Insert node a before node b.
 */
qq.insertBefore = function(a, b){
    b.parentNode.insertBefore(a, b);
};
qq.remove = function(element){
    element.parentNode.removeChild(element);
};

qq.contains = function(parent, descendant){
    if (parent.contains){
        return parent.contains(descendant);
    } else {
        return !!(descendant.compareDocumentPosition(parent) & 8);
    }
};

/**
 * Creates and returns element from html string
 * Uses innerHTML to create an element
 */
qq.toElement = (function(){
    var div = document.createElement('div');
    return function(html){
        div.innerHTML = html;
        var element = div.firstChild;
        div.removeChild(element);
        return element;
    };
})();

//
// Node properties and attributes

/**
 * Sets styles for an element.
 * Fixes opacity in IE6-8.
 */
qq.css = function(element, styles){
    if (styles.opacity != null){
        if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
            styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
        }
    }
    qq.extend(element.style, styles);
};
qq.hasClass = function(element, name){
    var re = new RegExp('(^| )' + name + '( |$)');
    return re.test(element.className);
};
qq.addClass = function(element, name){
    if (!qq.hasClass(element, name)){
        element.className += ' ' + name;
    }
};
qq.removeClass = function(element, name){
    var re = new RegExp('(^| )' + name + '( |$)');
    element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
};
qq.setText = function(element, text){
    element.innerText = text;
    element.textContent = text;
};

//
// Selecting elements

qq.children = function(element){
    var children = [],
    child = element.firstChild;

    while (child){
        if (child.nodeType == 1){
            children.push(child);
        }
        child = child.nextSibling;
    }

    return children;
};

qq.getByClass = function(element, className){
	if (typeof element == 'undefined') return []
    if (element.querySelectorAll){
        return element.querySelectorAll('.' + className);
    }

    var result = [];
    var candidates = element.getElementsByTagName("*");
    var len = candidates.length;

    for (var i = 0; i < len; i++){
        if (qq.hasClass(candidates[i], className)){
            result.push(candidates[i]);
        }
    }
    return result;
};

qq.formatSize = function(bytes, ed){
    var i = -1;
    do {
        bytes = bytes / 1024;
        i++;
    } while (bytes > 1024);

    if ( !ed ) return Math.max(bytes, 0.1).toFixed(2) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
        else return Math.max(bytes, 0.1);
};

qq.getRand = function(){
        var rand = Math.random().toString();
        return rand.substring(2);
};

qq._getNextFileId = function(notIncrease){
	var preValue = document.getElementById("nextId").value;
	if ( !notIncrease ) document.getElementById("nextId").value++;
	return preValue;
};

qq._getNextURLId = function(notIncrease){
	var hash = 'URL_';
	var preValue = document.getElementById("nextUrlId").value;
	if ( !notIncrease )
	{
		for (var c=0;c<10;c++)
		{
			var numm = (Math.random() * (c+1) ).toString();
			var base64 = jQuery.base64Encode(numm);
			hash += base64.substring(c+3, c+4);
		}
		document.getElementById("nextUrlId").value = hash.toUpperCase();
	}
	return preValue;
};

qq._count = function(obj){
	var len = 0;
	for (var k in obj) len++;
	return len;
};

qq._lockQueue = function(){
        var self = globSelf;
    self._isCanUploadList = false;
};

qq._unlockQueue = function(){
        var self = globSelf;
        self._isCanUploadList = true;
};

qq.getFileName = function(file){
/*
        var name;
        if ( file.value )
                name = file.value.replace(/.*(\/|\\)/, "");
        else
                name = file.fileName != null ? file.fileName : file.name;

        return name;
*/
        return $(file).val();
};

qq.removeFileFromQueue = function(elem, idx, fromHistory){
        idx = idx ? idx : $(elem).parent().parent().parent().attr("id");
        if ( idx )
        {
				if ( typeof qq._fileBuff[idx] == 'undefined' ) return;
                setTimeout('$("div#'+idx+'").remove();', 2000);
				var cVer = $.browser.codeversion.replace(/\./g, '');
				cVer = cVer.substr(0, 2);
                if ( !qq._fileBuff[idx]['remotefile'] && $.browser.firefox && cVer < 36 ) //!$.browser.msie && !$.browser.opera && !$.browser.chrome && !$.browser.safari )
                {
                        var frm = $(".qq-upload-button form[name='form_frame_"+idx+"']");
                        $(frm).attr("method", "GET").remove();
                        $("#frame_"+idx).attr("name", "NONE").remove();
                }
                if ( qq._fileBuff[idx]['submit'] )
                {
					globSelf._handler.cancel(idx - 1);
					globSelf.submitQueue = false;
					globSelf._startUploadByQueue();
				}

                qq.removeFromHistory(idx, fromHistory);
				globSelf._options.onAllComplete();
				globSelf.submitQueue = false;
				globSelf._isCanUploadList = true;
		}
				if ( qq._count(qq._fileBuff) <= 0 ) {
					globSelf.dirIsSet = '';
					globSelf._clearQueueUpload();
				}
        //}
};

qq.addHistoryFileName = function(obj, fileName, id, size, ifUrl){
        obj._options.nextId++;
        var fileNumm = parseInt(obj._options.nextId);
        qq._fileBuff[id] = { //fileNumm] = {
                "name": fileName,
                "size": size,
                "submit" : '',
                "submited" : '',
                "remotefile" : ( ifUrl ) ? ifUrl : false,
				"summ" : randomString(10)
        };

		$("form[name='form_frame_"+id+"'] input[name='UPLOAD_IDENTIFIER']").val(qq._fileBuff[id].summ);	
		var newAct = $("form[name='form_frame_"+id+"']").attr("action");
		$("form[name='form_frame_"+id+"']").attr("action", newAct+"&UPLOAD_IDENTIFIER="+qq._fileBuff[id].summ);
};

qq.removeFromHistory = function(id, fromServerHistory){
		if ( typeof(qq._fileBuff[id]) == 'undefined' ) return false;
		try
		{
			if ( fromServerHistory ) {
				var params = '?req=delete&fileID='+id;
				if ( qq._fileBuff[id]['submit'] == '1' ) {
					params += '&blockit=1';
				}
				if ( qq._fileBuff[id]['remotefile'] )
					params = '?remotefile=true&req=delete&fileID='+id;
		        $.ajax({
		                url: globSelf._options.action + params,
		                type: 'GET'
		        });
			}
	
			if ( typeof qq._fileBuff[id] != 'undefined' ) {
				qq._fileBuff[id] = "";
				delete qq._fileBuff[id];
			}
			if ( typeof window.sizeBKP != 'undefined' )
				if ( typeof window.sizeBKP[id] != 'undefined' )
					window.sizeBKP[id] = 0;
		} catch(e) {}
};

qq.startCheckProgress = function(id, force, loaded, cntHits){
        if ( typeof qq._fileBuff[id] == 'undefined' ) return;
        var size = qq._fileBuff[id]['size'];

        if ( qq._fileBuff[id]['remotefile'] )
        {
                if ( size > loaded )
                {
                     qq.setProgressBar(id, loaded, size);
                }
                else
                {
                     qq.setProgressBar(id, 100, 100);
                }
                return;
        }

        //var decim = qq.getDecim(size);
        var now = 0; // = loaded ? loaded : Math.round(size / decim);

		var fileSumm = qq._fileBuff[id]['summ'];
		$.ajax({
			url: ENV.uploaderScript+'?remotefile=false&fileID='+id+'&req=check',
			type: 'POST',
			data: 'summ='+fileSumm,
			success: function(data) {
				var res = eval('('+data+')');
				now = res.sizenow;
				if ( typeof qq._fileBuff[id]['loaded'] != 'undefined' ) {
					if ( now == 0 || !now ) {
						if ( cntHits >= 5 ) {
							try{clearTimeout(window.delay);}catch(e){}
							qq.setProgressBar(id, 100, 100);
							qq.onCompleteServe('{"success":true,"id":"'+id+'"}');
							return;
						}
						cntHits++;
						window.delay = setTimeout(function(){qq.startCheckProgress(id, true, now, cntHits);}, 500);
						return;
					}
				}
				if ( isNaN(parseInt(now)) ) {		
					if ( now != 0 ) qq._fileBuff[id]['loaded'] = now;
                }
				//if ( now == '0' ) now = 2;
				if ( now == loaded ) {
					if ( cntHits >= 5 ) {
						try{clearTimeout(window.delay);}catch(e){}
						qq.setProgressBar(id, 100, 100);
						qq.onCompleteServe('{"success":true,"id":"'+id+'"}');
						return;
					}
					cntHits++;
					window.delay = setTimeout(function(){qq.startCheckProgress(id, true, now, cntHits);}, 500);
					return;
				}
		        if ( size > now )
		        {
					if ( now > size ) now = size;
					qq.setProgressBar(id, now, size);
	                window.delay = setTimeout(function(){qq.startCheckProgress(id, true, now);}, 1000);
		        }
		        else
		        {
					try{clearTimeout(window.delay);}catch(e){}
	                qq.setProgressBar(id, 100, 100);
					qq.onCompleteServe('{"success":true,"id":"'+id+'"}');
		        }
			}
		});
};

qq.getDecim = function(bytes){
    var i = -1;
    do {
        bytes = bytes / 1024 / 5;
        i++;
    } while (bytes > 100);

    return Math.max(bytes, 0.1).toFixed(2);
};

qq.getStampStr = function(){
	var dd = new Date();
	var ms = dd.getHours()+':'+dd.getMinutes()+':'+dd.getSeconds()+':'+dd.getMilliseconds();
	return ms.replace(/:/g, "");
};

qq.speedTest = function(){
	var stmp = qq.getStampStr();
	var point1 = 0;
	var rr = new XMLHttpRequest();
	rr.open("POST", '/upload/server/', true);
	rr.send(null);
};

qq.setProgressBar = function(id, loaded, total, fatal, anime, hard){
        var percents = 100;
        var text;
	    var txtSize = qq.formatSize(total);
	    if ( qq.formatSize(total, true) <= 0.1 ) {
	        txtSize = qq.formatSize($.globLoadSize);
	    } else {
	        $.globLoadSize = total;
	    }
	    txtSize = '('+ txtSize +') -';
		try{clearInterval($.animateDelay);delete $.animateDelay;} catch(e) {}
		if ( anime ) {
			if ( loaded == total && !fatal && !$.browser.chrome ) {
				try{clearInterval($.animateDelay);delete $.animateDelay;} catch(e) {}
				text = '100% - Complete';
				$("div#"+id+" div.uploadifyProgressBar").attr("style", "");
				$("div#"+id+" span.qq-upload-size").text(text);
				return;
			}
			else {
				//$("div#"+id+" div.uploadifyProgressBar").attr("style", "width: 100%; background-color: rgb(255, 255, 255); background-image: url(/images/progress-bar.gif);");
/*
				if ( window.animeFakeDelay ) {
					clearInterval(window.animeFakeDelay);
					window.animeFakeDelay = setInterval(function(){
						var pos = parseInt(($("div#"+id+" div.uploadifyProgressBar").css("background-position")).split(" ")[1]);
						$("div#"+id+" div.uploadifyProgressBar").css("background-position", (pos + 1));
					}, 80);
				}
*/
				//text = txtSize+' Uploading';
				//$("div#"+id+" span.qq-upload-size").text(text);

				$.animatePerc = 1;
	            $.percAnime = parseInt(total / 1024 / 2) - 200;
				if ( $.percAnime > 1024 ) $.percAnime = 1000;
	            if ( $.percAnime < 100 ) $.percAnime = 100;
	            if ( typeof $.animateDelay == "undefined" ) {
		            $.animateDelay = setInterval(function(){
		                var prePerc = $.animatePerc;
		                if ( prePerc > 100 ) prePerc = 100;
		                $("div#"+id+" div.uploadifyProgressBar").width(prePerc+'%');
		                $("div#"+id+" span.qq-upload-size").text(txtSize+' '+prePerc+'%');
		                var incRand = parseInt((Math.random() * (5 - 1) + 1).toString()[0]);
		                $.animatePerc+=incRand;
		                if ( $.animatePerc >= 100 ) {
		                    try{clearInterval($.animateDelay);delete $.animateDelay;} catch(e) {}
		                    $("div#"+id+" span.qq-upload-size").text(txtSize+' 100%');
		                    $("div#"+id+" div.uploadifyProgressBar").attr("style", "width: 100%; background-color: rgb(255, 255, 255); background-image: url(/images/progress-bar.gif);");
		                    return;
		                }
		            }, $.percAnime);
				}
			}
			return;
		}
        if ( total > loaded )
        {
                percents = Math.round(loaded / total * 100);
				if ( percents <= 0 ) percents = 1;
                text = '('+qq.formatSize(total)+') - '+Math.round(loaded / total * 100)+'%';
        }
        if ( percents >= 100 && !fatal ) text = '100% - Complete';
		else if ( fatal ) text = '0% Error';
		if ( percents == 0 ) percents = 100;
        setTimeout(function(){$("div#"+id+" span.qq-upload-size").text(text);}, 1000);
        $("div#"+id+" div.uploadifyProgressBar").width(percents+'%');
};

qq.onCompleteServe = function(params){

		try{clearTimeout(window.delay)}catch(e){}

        if ( typeof params != 'object' )
                var res = eval('('+params+')');
        else
                var res = params;
        var ID = res.id;
        var message = 'Undefined server error!<br>Please try again.';
        if ( res.error ) message = res.error;
        else if ( res.problem ) message = res.problem;

		globSelf.submitQueue = false;
        if ( res.success )
        {
                //$("div#"+ID+" span.qq-upload-size").append(" - Complete");
                //$("div#"+ID+" div.uploadifyProgressBar").width('100%');
                qq.setProgressBar(ID, 100, 100);
                setTimeout(function(){$("div#"+ID).fadeOut(300);}, 300);
                qq.removeFileFromQueue('', ID, false);
				globSelf._startUploadByQueue();
        }
        else
        {
                if ( ID )
                {
                        $("div#"+ID).removeClass("qq-upload-success").addClass("uploadifyError");
                        $("div#"+ID+" span.qq-upload-hints")
                                .attr("hint", message)
                                .show();
                        qq.setHintsForElement($("div#"+ID+" span.qq-upload-hints"));
                        $("div#"+ID+" div.uploadifyProgressBar").css("background", "red");
                        qq.setProgressBar(ID, 100, 100, true);
                        //qq.removeFileFromQueue('', ID);
						globSelf._startUploadByQueue();
                }
        }

		globSelf._options.onAllComplete();
		//globSelf.submitQueue = false;
		//globSelf._startUploadByQueue();
};

qq.showPromptURL = function() {
    var self = globSelf;
    this.winTitle = 'Upload a File from the Internet <img style="margin: 2px 3px 0px 0px;float:right;display:none;" id="LoadingURLFileICO" src="/images/ajax-loader.gif" />';
    this.defUrl = (typeof window.globRemoteUrlFile != "undefined")?decodeURIComponent(window.globRemoteUrlFile):"";
	window.globRemoteUrlFile = "";
    this.sHtml = 'URL: <input type="text" id="rfFileURL" class="filedText" value="'+this.defUrl+'" /><br><i>ex: http://domain.com/filename.pdf</i>';
    this.request = null;
	var FileUrl;
    $.showPrompt(
        this.winTitle, this.sHtml,
		function(){
            try{
                $.loadRemoteUrlRequest.abort();
                $.loadRemoteUrlRequest = null;
                window.console.clear();
            } catch(e) {}
        },
        function(){
			$("img#LoadingURLFileICO").show();
            FileUrl = $.trim($("#rfFileURL").val());
			if ( typeof(filesNum) != "undefined" ) {
				if ( filesNum > 0 ){
					backToUpload();
				}
			}
			window.globRemoteUrlFile = escape(FileUrl);
			if ( !FileUrl ){
				self._error('emptyUrlError', FileUrl, this.winTitle, qq.showPromptURL);
				return false;
			}
			if ( FileUrl.toLowerCase().indexOf('http://') == -1 )
				FileUrl = 'http://'+FileUrl;
			if ( FileUrl.toLowerCase().indexOf('https://') != -1 )
				FileUrl = 'http://'+FileUrl;
            var shortUrl = '';
            if ( FileUrl.length > 35 ) shortUrl = FileUrl.substring(0, 15)+'....'+FileUrl.substring(FileUrl.length-15);
			if ( qq._count(qq._fileBuff) >= self._options.limitFiles ){
				self._error('filelimitError', shortUrl, this.winTitle, qq.showPromptURL);
				return false;
			}
			if ( !$.isURL(FileUrl.toLowerCase()) )
			{
				self._error('UrlError', FileUrl, this.winTitle, qq.showPromptURL);
				return false;
			}
			$.remoteCntHits = 0;
			FileUrl = escape(FileUrl);
			_getRemoteFileData(FileUrl, function(RMFD){
				FileUrl = unescape(FileUrl);
				var self = globSelf;
				if ( !RMFD ){
					self._error('serverError2', FileUrl, winTitle, qq.showPromptURL);
					return false;
				}
				if ( typeof RMFD != 'object' ) RMFD = eval('('+RMFD+')');
				if ( typeof RMFD.status == 'undefined' && RMFD.error == "Incorrect URL" ) {
                    self._error('UrlError', FileUrl, this.winTitle, qq.showPromptURL);
                    return false;
                }
				if ( RMFD.error && typeof RMFD.status != 'undefined' && RMFD.status == "504 Gateway Timeout" ) {
					self._error('notUrlError', FileUrl, this.winTitle, qq.showPromptURL);
					return false;
				}
	            if ( RMFD && RMFD.success )
	            {
					FileUrl = RMFD.realurl;
					FileUrl = unescape(FileUrl);
					var fileName = FileUrl.replace(/.*(\/|\\)/, "");
					var shortUrl = '';
					if ( FileUrl.length > 35 ) shortUrl = FileUrl.substring(0, 15)+'....'+FileUrl.substring(FileUrl.length-15);
					
	                if ( !self._isAllowedExtension(FileUrl) ) {
	                    self._error('typeError', shortUrl, this.winTitle, qq.showPromptURL);
						return false;
					}
					else if (self._isPresentInList(fileName)) {
						self._error('samefileError', shortUrl, this.winTitle, qq.showPromptURL);
						return false;
					}
	                else
	                {
	                    if ( RMFD.status == '200' ) {
							qq.addURLFileToList(this.winTitle, FileUrl, shortUrl, RMFD);
							window.globRemoteUrlFile = "";
							dialog.hideDialog();
							return true;
	                    } else {
							self._error('notUrlError', FileUrl, this.winTitle, qq.showPromptURL);
							return false;
	                    }
	                }
	            }
	            else if ( ! self._isAllowedExtension(FileUrl) )
	            {
	                self._error('typeError', shortUrl, this.winTitle, qq.showPromptURL);
					return false;
	            }
	            else
	            {
					self._error('UrlError', FileUrl, this.winTitle, qq.showPromptURL);
					return false;
	            }
		    });
        }
    );
    setTimeout(function(){$("#rfFileURL").focus();}, 100);

    function _getRemoteFileData(filePath, cbkFunc)
    {
		var idx = $("#nextUrlId").val();
        $.loadRemoteUrlRequest = $.ajax({
            url: ENV.remoteFSize+'?GetRemoteFileData=true',
            type: 'POST',
            data: "GetRemoteFileData=true&remotefile="+filePath+"&fileID="+idx,
            dataType: 'json',
            //async: false
			success: function(data) {
				var res = eval ( data );
				if ( res.error ) {
					if ( res.status == "504 Gateway Timeout" ) {
						if ( $.remoteCntHits >= 5 ) {
							cbkFunc(data);
							return;
						}
						$.remoteCntHits++;
						_getRemoteFileData(filePath, cbkFunc);
						return;
					}
				} else {
					cbkFunc(data);			
				}
			}
        });
    };
};

qq.addURLFileToList = function(winTitle, fullUrl, shortUrl, respInfo){
        var self = globSelf;
        qq._lockQueue();
        var fileName = fullUrl.replace(/.*(\/|\\)/, "");
        var size = respInfo.size;

		if ( qq._count(qq._fileBuff) >= self._options.limitFiles ){
			self._error('filelimitError', shortUrl, winTitle, qq.showPromptURL);
			return false;
		} else if ( ! self._isAllowedExtension(fileName)){
			self._error('typeError', shortUrl, winTitle, qq.showPromptURL);
			return false;
        } else if (size === 0){
                self._error('emptyError', shortUrl, winTitle, qq.showPromptURL);
                return false;
        } else if (size && self._options.sizeLimit && size > self._options.sizeLimit){
                self._error('sizeError', shortUrl, winTitle, qq.showPromptURL);
                return false;
        } else if (self._isPresentInList(fileName)){
                self._error('samefileError', shortUrl, winTitle, qq.showPromptURL);
                return false;
        }
		var _fName = $.base64Encode(fileName);
		var _oldID = $("#fileQueue div.uploadifyQueueItem[filename='"+_fName+"']").attr("id");
		if ( _oldID ) {
			$("#"+_oldID).fadeOut(300);			
			setTimeout(function(){$("#"+_oldID).remove();}, 200);	
		}

		var idx = qq._getNextURLId();
        if ( respInfo.realurl ) fullUrl = respInfo.realurl;
        self._addHistoryFileName(fileName, idx, size, fullUrl);
        var item = qq.toElement(self._options.fileTemplate);
        item.id = idx;
		$(item).attr("filename", $.base64Encode(fileName));
		self._getElement(item, 'size').innerHTML = '<img class="loading" src="/images/upl/loading.gif" />';
        var fileElement = self._getElement(item, 'file');
        var sizeElement = self._getElement(item, 'size');
        qq.setText(fileElement, self._formatFileName(fileName));
        qq.setText(sizeElement, ' ('+self._formatSize(size)+')');
        qq.attach(self._getElement(item, 'cancel'), 'click', function(e){
                e = e || window.event;
                var target = e.target || e.srcElement;
                if ( $(target).parent().parent().hasClass(self._classes.cancel) )
                {
                        qq.preventDefault(e);
                        var itemIco = target.parentNode;
                        $(item).fadeOut(200);
                        var idx = $(target).parent().parent().parent().attr("id");
                        self._removeFileFromQueue(target, idx, true);
                }
        });

		if ( !self._options.onlyInitCore )
			self._getElement('list').appendChild(item);
		else
			$("#fileQueue").get(0).appendChild(item);
        self._filesInProgress++;
        qq._unlockQueue();
        if ( !self._options.onlyInitCore && !self._options.isAttachedEventsBtns) self._attachBtnsEvents();
};

qq.startUploadURLFile = function(id){
    if ( typeof qq._fileBuff[id] == 'undefined' ) return;
    var size = qq._fileBuff[id]['size'];
    var name = qq._fileBuff[id]['name'];
    var url = qq._fileBuff[id]['remotefile'];
    var req = $.ajax({
        url: ENV.uploaderScript+'?remotefile=true&req=start&fileID='+id,
        type: 'POST',
        dataType: 'json',
        async: false
    });
    var res = req.responseText;
    qq.checkUploadedURLSize(id);
};

qq.checkUploadedURLSize = function(id, cntHits){
	if ( !cntHits ) cntHits = 0;
    if ( typeof qq._fileBuff[id] == 'undefined' ) return;
    var size = parseInt(qq._fileBuff[id]['size']);
    var name = qq._fileBuff[id]['name'];
    var url = qq._fileBuff[id]['remotefile'];
    var req = $.ajax({
        url: ENV.uploaderScript+'?remotefile=true&fileID='+id+'&req=check',
        type: 'POST',
        async: false
    });

	var res = {};
	if (req.statusText != "OK") res.error = "true";
    var res = req.responseText;
	if ( !res ) res.error = "true";
    res = eval('('+res+')');
	if ( res.error )
	{
		if ( cntHits >= 5 )
		{
			qq.onCompleteServe(res);
			setTimeout(function(){qq.removeFromHistory(res.id, true);}, 200);	
			return;
		}
		cntHits++;
		setTimeout(function(){qq.checkUploadedURLSize(id, cntHits);}, 1000);
		return;
	}
	var loaded = parseInt(res.sizenow);
	if ( typeof window.sizeBKP == 'undefined' ) window.sizeBKP = {};
	if ( window.sizeBKP[id] == loaded ) {
		window.sizeBKP[id] = loaded;
		if ( cntHits >= 10 )
		{
			qq.onCompleteServe('{"error":"Sorry. Can\'t load file from remote server.","id":"'+res.id+'"}');
			setTimeout(function(){qq.removeFromHistory(res.id, true);}, 200);
			window.sizeBKP[id] = 0;
			return;
		}
		cntHits++;
		setTimeout(function(){qq.checkUploadedURLSize(id, cntHits);}, 1000);
		return;
	}
	window.sizeBKP[id] = loaded;
	if ( size > loaded )
	{
		qq.setProgressBar(id, loaded, size);
		setTimeout(function(){qq.checkUploadedURLSize(id);}, 500);
	}
	else
	{
		qq.setProgressBar(id, 100, 100);
		qq.onCompleteServe('{"success":true,"id":"'+res.id+'"}');
	}
};

qq._flashUploaderError = function(l,h,k,j){
	var ID = "FLASH_uploadify"+h;
	var info = l.type;
	var code = j.info;
	var type = j.type;

	var message = code+" "+type+" Error";

	if ( !message ) message = 'Undefined server error!<br>Please try again.';

	$("div#uploadify"+h)
		.removeClass("qq-upload-success")
		.addClass("uploadifyError");
	$("div#uploadify"+h+" span.percentage").html("").append('<span class="qq-upload-hints" style="display:none;"> - More info</span>');
	$("div#uploadify"+h+" span.qq-upload-hints")
		.attr("hint", message)
		.show();
	qq.setHintsForElement($("div#uploadify"+h+" span.qq-upload-hints"));
	$("#uploadify"+h+"ProgressBar").css("background", "red");

	qq.removeFromHistory(ID);

	return false;
};

qq._flashUploaderQueue = function(ID){
	if ( !ID ){
		for ( key in qq._fileBuff ){
			if ( "FLASH_uploadify" == key.substring(0, 15) ) return true;
			break;
		}
	}
	//$.log(ID);
	var flashID = "FLASH_uploadify"+ID;
	if ( typeof qq._fileBuff[flashID] != 'undefined' )
		qq.removeFromHistory(flashID);
	
	if ( globSelf.submitQueue ) globSelf.submitQueue = false;
	globSelf._startUploadByQueue();
	return true;	
};

qq._flashRemoveFromQueue = function(idx, bulk){
	if ( idx )
	{
		idx = "FLASH_uploadify"+idx;
		if ( typeof qq._fileBuff[idx] == 'undefined' ) return true;
		qq._fileBuff[idx] = "";
		delete qq._fileBuff[idx];
	}

	if ( bulk )
	{
		$("#fileQueue div[id*='URL_']").each(
			function(numm, elem) {
				var idx = $(this).attr('id');
				$(this).fadeOut(200);
				qq.removeFileFromQueue('', idx, true);
			}
		);
	}

	return true;
};

qq._flashValidateFile = function(j,h,file){
	var self = globSelf;
	var name = file.name;
	var size = file.size;
	var mime = file.type;
	var winTitle = 'Upload Error';

	if ( typeof(filesNum) != "undefined" ) {
		if ( filesNum > 0 ){
			backToUpload();
		}
	}

	if ( qq._count(qq._fileBuff) >= self._options.limitFiles ){
		self._error('filelimitError', name, winTitle);
		return false;
	} else if ( ! self._isAllowedExtension(name)){
		self._error('typeError', name, winTitle);
		return false;
	} else if (size === 0){
		self._error('emptyError', name, winTitle);
		return false;
	} else if (size && self._options.sizeLimit && size > self._options.sizeLimit){
		self._error('sizeError', name, winTitle);
		return false;
	} else if (self._isPresentInList(name)){
		self._error('samefileError', name, winTitle);
		return false;
	}

	$("#uploadifyUploader").blur();
	$("#fileQueue").focus();
	return true;
};

qq.setHintsForElement = function(elm) {
        $(elm).attr("title", "Error: "+$(elm).attr("hint"));
/*
                .mouseenter(
                        function(e) {
                                var boxHint = $("#box_hint");
                                var sInfo = "";
                                var sHtml = "";
                                sInfo = $(this).attr("hint");
                                sHtml += "<div class='text_emphasis'><b>Description off problem:</b></div>\n";
                                sHtml += "<div class='text_center'>" + sInfo + "</div>\n";
                                boxHint.html(sHtml);
                                boxHint.fadeIn(200);
                        }
                )
                .mousemove(
                        function(e) {
                                //var pos = new $.mousePos(e, {wide: $(".upContainer").width(), high: $(".upContainer").height()});
								var wb = $(".upContainer").width();
								var hb = $(".upContainer").height();
								var pos = {
									x: ( (e.clientX > wb ) ? (e.clientX - wb) : (wb - e.clientX) ),
									y: e.clientY
								};
                                var criteria = 280;
                                var boxHint = $("#box_hint");
                                var max = $(".upContainer").width() - criteria;
                                if (pos.x > max) pos.x = pos.x - criteria;
								$.log(dump(pos)+" - "+max);
                                boxHint.css("left", pos.x + 10);
                                boxHint.css("top", pos.y + 20);
                        }
                )
                .mouseleave(
                        function() {
                                $("#box_hint").fadeOut(300);
                        }
                );
*/
};

