qq.FileUploaderCalico = function(o){
    // call parent constructor
    qq.FileUploaderBasic.apply(this, arguments);
    
    // additional options    
    qq.extend(this._options, {
        element: null,
        // if set, will be used instead of qq-upload-list in template
        listElement: null,
        multiple: false, 
        template:	
			'<span class="l button large round qq-upload-button" href="#">' +
			'	Upload an image' +
			'</span>',

        // template for one item in file list
        fileTemplate: 
			'<li>' +
			'	<span class="qq-in-progress">' +
			'		<span class="qq-upload-size"></span>' +
			'		<span class="qq-upload-spinner"></span>' +
			'		<a class="qq-upload-cancel" href="#">Cancel</a>' +
			'	</span>' +
			'	<span class="qq-upload-success">Upload complete, please save changes</span>' +
			'	<span class="qq-upload-fail">Upload failed, please try again</span>' +
            '</li>',
        
        classes: {
            // used to get elements from templates
            button: 'qq-upload-button',
                     
            progress: 'qq-in-progress',
			size: 'qq-upload-size',
            spinner: 'qq-upload-spinner',
            cancel: 'qq-upload-cancel',

            // added to list item when upload completes
            // used in css to hide progress spinner
            success: 'qq-upload-success',
            fail: 'qq-upload-fail'
        }
    });
    // overwrite options with user supplied    
    qq.extend(this._options, o);       

    this._element = this._options.element;
    this._element.innerHTML = this._options.template;        
    this._listElement = this._options.listElement;
    
    this._classes = this._options.classes;
    
    this._button = this._createUploadButton(this._find(this._element, 'button'));        
    
    this._bindCancelEvent();
};
qq.extend(qq.FileUploaderCalico.prototype, qq.FileUploaderBasic.prototype);
qq.extend(qq.FileUploaderCalico.prototype, {
    /**
     * Gets one of the elements listed in this._options.classes
     **/
    _find: function(parent, type){                                
        var element = qq.getByClass(parent, this._options.classes[type])[0];        
        if (!element){
            throw new Error('element not found ' + type);
        }
        
        return element;
    },
    _onSubmit: function(id, fileName){
        qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
        this._addToList(id, fileName);  
    },
    _onProgress: function(id, fileName, loaded, total){
        qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);

        var item = this._listElement;
        var size = this._find(item, 'size');
        size.style.display = 'inline';
        
        var text; 
        if (loaded != total){
            text = '( ' + Math.round(loaded / total * 100) + '% of ' + this._formatSize(total) + ' )';
        } else {                                   
            text = '( 100% of ' + this._formatSize(total) + ' )';
        }
        
        qq.setText(size, text);         
    },
    _onComplete: function(id, fileName, result){
        qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);

        // mark completed
        var item = this._listElement;                
        this._find(item, 'progress').style.display = 'none';
		
        if (result.success){
            this._find(item, 'success').style.display = 'inline';   
        } else {
            this._find(item, 'fail').style.display = 'inline';
        }         
    },
    _addToList: function(id, fileName){
        var item = qq.toElement(this._options.fileTemplate);                
        item.qqFileId = id;

        this._find(item, 'size').style.display = 'none';
        this._find(item, 'success').style.display = 'none';
        this._find(item, 'fail').style.display = 'none';
        this._listElement.innerHTML = item.innerHTML;
    },
    /**
     * delegate click event for cancel link 
     **/
    _bindCancelEvent: function(){
        var self = this,
            list = this._listElement;            
        
        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);
            }
        });
    }    
});
