

var AjaxUploader = {
  
  patch: function() {
    $$('div.uploader input[type="file"]').each(function(i) {
      if(!i.onchange) i.onchange = function() { AjaxUploader.upload(this); };
      
    });
    window.setTimeout(function() {
      $$('div.uploader img.preview').each(function(i) {
        AjaxUploader.patchPreview(i);
      });
    }, 10);
  },
  
  patchPreview: function(img) {
    if(img) {
      
      if(img.complete && img.width && img.height) {
        img.style.display = "block";
        AjaxUploader.computePreviewDimensions(img);
        AjaxUploader.scaleTo("preview", img);
        img.onclick = function() {
          if(this._previewStatus > -1) {
           AjaxUploader.scaleTo(this._previewStatus == 0 ? "preview" : "original", this);
           this.style.zIndex = 200;
          }
        }
        
        img.onmouseout = function() {
          AjaxUploader.scaleTo("preview", this);
          this.style.zIndex = 20;
        }
      } else {
      
        Element.setOpacity(img, 0);
        img.style.display = "block";
        img.onload = function() {
          AjaxUploader.patchPreview(this);
        };
        
      }
    }
  },
  
  findParent: function(i) {
    var p = i.parentNode;
    while(p && !Element.hasClassName(p, "uploader")) p = p.parentNode;
    return p;
  },
  
  upload: function(i) {
    var now = new Date().getTime();
    if(now - (i._lastClickTime || 0) < 200) return; 
    i._lastClickTime = now;
    
    var p = this.findParent(i);
    if(!p) return;
    
    var f = i.form;
    var frameName = f.id.replace(/form$/, "frame-" + i.id);
    f.enctype = "multipart/form-data";
    if(!f.target) {
      f.target = frameName;
      f.action = f.action.replace(/\/(update\b|create\b\/.*)/, "/upload");
      f._uploader_onsubmit = f.onsubmit;
      f.onsubmit = function(ev) {
        return ((!AjaxUploader.isUploading(this)) || 
            confirm("Alcuni allegati sono in fase di invio verso il server. Se si salva in questo momento, gli allegati potrebbero andare persi. Continuare comunque?")
            ) && this._uploader_onsubmit();
      }
    }
    
    
    
    if(!$(frameName)) {
    
      var extras = document.createElement("div");
      extras.className = "uploader-extras";
      
      function addExtraField(name, value) {
        var field = document.createElement("input");
        field.type = "hidden";
        field.name = name;
        field.value = value;
        extras.appendChild(field);
      }
      
      addExtraField("model_name", i.name.replace(/\[.*/, ""));
      addExtraField("field_name", i.name.replace(/.*\[(.*?)\].*/, "$1"));
      addExtraField("form_id", f.id);
      
      var iframe = document.createElement("iframe");
      iframe.name = iframe.id = frameName;
      iframe.style.position = "absolute";
      iframe.style.width = "0px";
      iframe.style.height = "0px";
      iframe.style.borderWidth = "0px";
      iframe.style.opacity = "0";
      extras.appendChild(iframe);
      
      var indicator = $$('img.loading-indicator')[0].cloneNode(true);
      indicator.id = "";
      indicator.style.display = "inline";
      extras.appendChild(indicator);
      extras.appendChild(document.createTextNode("Loading file..."));
      if(i.nextSibling) {
        i.parentNode.insertBefore(extras, i.nextSibling);
      } else {
        i.parentNode.appendChild(extras);
      }
    }
    
    var img = new Selector("img.preview").findElements(p).first();
    if(img) {
      AjaxUploader.scaleTo("preview", img);
      new Effect.Opacity(img, { from: 1.0, to: 0.0 });
    }
    f.submit();
  },
  
  afterLoad: function(formId, frameDoc) {
    var srcDiv = frameDoc.getElementsByTagName("div")[0];
    $$("#" + formId + " div.uploader").each(function(targetDiv) { 
      var iframe = $$("div.uploader-extras iframe")[0];
      if(iframe && iframe.contentWindow.document == frameDoc) { 
        var targetError = new Selector('.error').findElements(targetDiv)[0];
        if(srcDiv.className == "error") { 
          if(!targetError) {
            targetError = document.createElement("div");
            targetError.className = "error";
            targetDiv.appendChild(targetError);
          }
          targetError.innerHTML = srcDiv.innerHTML;
          targetError.show();
        } else {
          if(targetError) targetError.hide();
          var ii = srcDiv.getElementsByTagName("input");
          var ti;
          for(var j = ii.length; j-- > 0;) {
            if((ti = new Selector('input[name="' + ii[j].name + '"]').findElements(targetDiv).first()) &&
              ti.type == "hidden") {
              ti.value = ii[j].value;
              var a = srcDiv.getElementsByTagName("a")[0];
              if(a && a.href) {
                var img = new Selector('img.preview').findElements(targetDiv).first();
                if(img) {
                  img.onload = function() {
                    AjaxUploader.computePreviewDimensions(img);
                    AjaxUploader.scaleTo("preview", img);
                    new Effect.Opacity(img, { from: 0.0, to: 1.0 });
                  }
                  img.src = a.href;
                }
              }
            }
          }
        }
        
        var extras = new Selector('div.uploader-extras').findElements(targetDiv)[0];
        if(extras) {
          extras.parentNode.removeChild(extras);
        }
        throw $break;
      }
    });
  },
  
  scaleTo: function(destination, img) {
    var d = img[destination + "Dimensions"];
    if(!d) return;
    img._previewStatus = (destination == "preview") ? 1 : 0;
    img.style.width = d.width + "px";
    img.style.height = d.height + "px";
    img.style.cursor = (img._previewStatus) ? "se-resize" : "nw-resize";
  },
  
  
  computePreviewDimensions: function(img) {
    img.style.width = "";
    img.style.height = "";
    
    
    var maxW = 150, maxH = 150;
    if(Element.hasClassName(img.parentNode, "preview-container")) {
      maxW = img.parentNode.offsetWidth;
      maxH = img.parentNode.offsetHeight;
    }
    
    var d = img.originalDimensions = { width: img.width, height: img.height };
    
    if(img.width > 0 && img.height > 0 &&
      (img.width > maxW || img.height > maxH)) {
      var imgRatio = img.width / img.height;
      var boxRatio = maxW / maxH;
      d = (imgRatio >= boxRatio) ? {
        width: maxW,
        height: Math.round(  maxW / imgRatio)
      } : {
        width: Math.round(maxH * imgRatio),
        height: maxH
      }
    }
    img.previewDimensions = d;
    return img;
  },
  
  isUploading: function(context) {
    return new Selector('div.uploader-extras').findElements(context || document.body).length != 0;
  }
};
