/*
 * Depende de jquery.json.js
 */
(function($) {
  $.uploader = {};
  $.uploader.version = '0.2';
  $.uploader.options = {
    allowedExt: [],
    beforeUpload: null,
    className: 'js_uploader',
    forceCreateForm: false,
    id:        'js_uploader',
    name:      'js_uploader',
    noReplace: false, // Se true desabilita a substituição do campo de upload
    onResponse: null,
    onChangeFile: null,
    size:      50,
    url: ''
  };
  var self = this;

  this.formUrl = '';
  this.tmpFileField = null;
  
  this.extensionCheck = function(filename) {
    if (!$.uploader.options.allowedExt.length || filename == '') return true;
    var result = filename.match(/.+\.(.+)$/i);
    return $.inArray(result[1], $.uploader.options.allowedExt) > -1;
  };
  
  /**
   * Limpa o campo file
   * @param {DOMElement} fileElement Input do tipo file
   */
  this.clearFileField = function(fileElement) {
    var field = $('<input type="file" />').change(self.onChangeEvent);
    var attrs = fileElement.attributes;
    for (var i = 0; i < attrs.length; i++) {
      if (attrs[i].name == 'type') continue;
      switch (attrs[i].name) {
        case 'class':
        case 'id':
        case 'name':
        case 'size':
          field.attr(attrs[i].name, attrs[i].value);
          break;
        case 'style':
          field.attr('style', $(fileElement).attr('style'));
      }
    }
    $(fileElement).replaceWith(field);
  };
  
  this.upload = function(element) {
    var form;
    var inputFile = $(element);
    var inputFileId = '#' + $(element).attr('id');
    
    form = inputFile.parents('form');
    
    self.formUrl = form.attr('action');
    form.attr('action', $.uploader.options.url);
    
    // Cria o IFRAME que vai receber a resposta do servidor
    if (!$('#js_iframeUploader').length) {
      form.append('<iframe name="js_iframeUploader" id="js_iframeUploader"></iframe>');
      
      var io = $('#js_iframeUploader')[0];
      var op8 = $.browser.opera && window.opera.version() < 9;
      if ($.browser.msie || op8) 
        io.src = 'javascript:false;document.write("");';
      $(io).css({
        position: 'absolute',
        top: '-1000px',
        left: '-1000px'
      });
      
      $('#js_iframeUploader').load(function(){
        responseText = $('#js_iframeUploader')[0].contentWindow.document.body.innerHTML;
        if (responseText) {
          var responseJSON = $.evalJSON(responseText);
          if ($.isFunction($.uploader.options.onResponse)) {
            $.uploader.options.onResponse(responseJSON, $(inputFileId)[0], responseJSON[0] ? self.replaceData(responseJSON[1]) : null);
          }
          // Se a resposta for sucesso, substitui o campo file
          if (!$.uploader.options.noReplace && responseJSON[0]) {
            self.replaceFileField($(inputFileId)[0], responseJSON[1]);
            return;
          }
          self.clearFileField($(inputFileId)[0]);
        }
      });
    }
    form.attr('target', 'js_iframeUploader');
    // ---
    
    if ($.isFunction($.uploader.options.beforeUpload)) {
      if ($.uploader.options.beforeUpload(form[0]) === false) return;
    }
    form.submit();
    form.attr('action', self.formUrl);
    form.removeAttr('target');
  };
  
  this.replaceData = function(fileProp) {
    var result = $('<div id="js_uploader_success"></div>');
    
    var size = Math.floor(fileProp.size/1024);
    $('<span></span>').text('» ' + fileProp.name + ' (' + (size == 0 ? fileProp.size + ' bytes)' : size + ' KiB)'))
    .appendTo(result);
    
    $('<span>&nbsp;<button id="js_uploader_changeFile" type="button">Trocar</button></span>')
    .appendTo(result);
    
    return result;
  };
  
  /**
   * Substitui o campo file por um div contendo a informação do arquivo enviado,
   * e anexa um link para trocar o arquivo
   * 
   * @param {DOMElement} fileElement Input do tipo file 
   * @param {Object} fileProp Propriedades do arquivo enviado
   */
  this.replaceFileField = function(fileElement, fileProp) {
    var div = self.replaceData(fileProp);
    self.tmpFileField = $(fileElement).clone(true);
    $(fileElement).replaceWith(div);
    
    $('#js_uploader_changeFile').click(function() {
      $(this).parent().parent().replaceWith(self.tmpFileField);
      self.clearFileField(self.tmpFileField[0]);
      if ($.isFunction($.uploader.options.onChangeFile))
        $.uploader.options.onChangeFile($('#' + self.tmpFileField.attr('id')));
      self.tmpFileField = null;
    });
  };
  
  this.onChangeEvent = function() {
    if (!self.extensionCheck(this.value)) {
      self.clearFileField(this);
      alert('Arquivo de tipo inválido.');
      return false;
    }
    var el = this;
    window.setTimeout(function() {
      self.upload(el);
    }, 1000);
  };
  
  
  $.loadUploader = function(inputFileId, opt) {
    opt = opt != undefined ? opt : {};
    $.extend($.uploader.options, opt);
    var inputFile = $(inputFileId);
    var form;
    // Verifica se o elemento é um INPUT do tipo FILE, caso contrário mostra
    // uma mensagem de erro e não faz nada
    if (inputFile.attr('type') != 'file') {
      alert('jQuery.uploader: O elemento não é do tipo FILE.');
      return;
    }
    
    // Caso o formulário não existir, será criado
    if (($.uploader.options.forceCreateForm && inputFile.parent().attr('id') != 'js_frmUploader') || !inputFile.parents('form').length) {
      form = $('<form id="js_frmUploader" method="post" enctype="multipart/form-data"></form>');
      inputFile.wrapAll(form);
    }
    
    inputFile.change(self.onChangeEvent);
  };
})(jQuery);
