Event.observe(window, "load", function() {UploadManager.setup()}, false);

var UploadManager = {

  currentlyUploadingKey: [],
  
  requests_for_keys: 0,

  uploading: function() {

    return UploadManager.currentlyUploadingKey.length != 0 ||
            UploadManager.requests_for_keys != 0;

  },

  setup: function() {

    var temp = new Image();
    [ "/images/vault/upload/upload-window/choose-another-file-button.png",
      "/images/vault/upload/upload-window/upload-label.png",
      "/images/vault/upload/upload-window/fade-out.png",
      "/images/vault/upload/upload-window/upload-background.png",
      "/images/delete.png",
      "/images/vault/upload/upload-window/upload-bar-tail.gif",
      "/images/vault/upload/upload-window/upload-mask.png",
      "/images/vault/upload/upload-window/upload-label.png",
      "/images/user/tier_stripes.png",].each(function(thisImage){
      temp.src = thisImage;
    });

    if ( !$("UploadWindow") ) return

    document.getElementsByClassName("uploadChooseFile")[1].value = "";

  },

  getUploadKey: function(handler) {
    // assemble the address for fetching the key, rnd query is to keep IE from caching
    var address = "/upload/new_upload_key" + ("?rnd=" + Math.random() * 99999);
    return new Ajax.Request(address, {method: "get", onSuccess: handler});
  },

  fileChosen: function(inputEl) {


    // get the form that this file input is in
    var form = inputEl.parentNode;

    // if the body doesn't have the class "someFileUploaded" then add it
    if (!Element.hasClassName(document.body, "someFileUploaded"))
      Element.addClassName(document.body, "someFileUploaded")

    // if we're not currently uploading then begin the upload
    if (!UploadManager.uploading())  {
      setTimeout(function(){UploadManager.startUpload(form);}, 0);
    // if we are currently uploading when a file is chosen, set it's label to "waiting"
    } else {
      // get the progress bar for the new form
      uploadProgress = document.getElementsByClassName("uploadProgress", form)[0];

      // make the progress bar visible and, if we're currently upload, set the label and class to "waiting"
      if (UploadManager.uploading()) {
        Element.addClassName(newestForm, "waiting");
        uploadLabel = document.getElementsByClassName("uploadProgressLabel", uploadProgress)[0];
        new Effect.Rewriter(uploadLabel, "waiting...");
      }
    }

    UploadManager.displayFileName(form);

    // create a new upload form
    UploadManager.addNewForm();



    // get the progress bar for the new form
    uploadProgress = document.getElementsByClassName("uploadProgress", form)[0];

    // make the progress bar visible and, if we're currently upload, set the label and class to "waiting"
    UploadManager.revealUploadProgress(uploadProgress);

    // // hide this forms upload button and file input
    UploadManager.hideUploadButton(form);

  },

  startUpload: function(uploadForm) {

    // get the upload progress label and set it to "starting"
    var uploadLabel = document.getElementsByClassName("uploadProgressLabel", uploadForm)[0];
    Element.addClassName(uploadForm, "uploading");
    Element.removeClassName(uploadForm, "waiting");

    // get the upload progress label and set it to "starting"
    var uploadLabel = document.getElementsByClassName("uploadProgressLabel", uploadForm)[0];
    new Effect.Rewriter(uploadLabel, " uploading...");

    UploadManager.requests_for_keys += 1;

    // assemble the address for fetching the key, rnd query is to keep IE from caching
    var address = "/upload/new_upload_key" + ("?rnd=" + Math.random() * 99999);
    return new Ajax.Request(address, {method: "get", onSuccess: function(req) {
      UploadManager.requests_for_keys -= 1;
      UploadManager.startUploadWithKey(req.responseText, uploadForm);
    }});

  },

  startUploadWithKey: function(uploadKey, uploadForm) {

    

    // store upload key in a globally accessble array
    UploadManager.currentlyUploadingKey.push(uploadKey);

    // set the form action, give it the class "uploading", and submit the form
    uploadForm.action = "/upload/new/file?upload_key=" + uploadKey;

    uploadForm.setAttribute("id", "UploadForm_" + uploadKey);
    uploadForm.submit();

    // get the progress bar for this form
    var uploadProgress = document.getElementsByClassName("uploadProgress", uploadForm)[0];

    // begin checking for progress on the upload
    UploadManager.checkProgress(uploadKey, uploadProgress);
  },

  checkProgress: function(uploadKey, uploadProgress) {

    // if there is an attempt to check progress on an upload who's key
    // isn't in the globally accessible array then bail on the check
   if (!UploadManager.currentlyUploadingKey.include(uploadKey)) return

    // if the upload has already completed then abort and avoid future checking of progress
   if (!UploadManager.uploading()) return

    // assemble the address for fetching the progress, rnd query is to keep IE from caching
   address = "/upload/progress?" + ("rnd=" + Math.random()) + "&upload_key=" + uploadKey;

    // fetch progress information
    progressAjax = new Ajax.Request(address, {method: "get", onSuccess: function(response) {
      Element.addClassName(uploadProgress.parentNode, "uploading");
      UploadManager.receiveProgress(response, uploadKey, uploadProgress);
    }});

    // call checkProgress() again in three seconds
    setTimeout(function() { UploadManager.checkProgress(uploadKey, uploadProgress); }, 3000);

  },

  receiveProgress: function(response, uploadKey, uploadProgress) {
    
    var update_the_page = function(recv_bytes, size_bytes, percent) {
      var recv_megs = UploadManager.roundToHundredths(recv_bytes / 1048576);
      var size_megs = UploadManager.roundToHundredths(size_bytes / 1048576);
      // get the label in this progress bar and set it contents to the new values
      $$("#UploadForms .uploadProgressLabel").first().innerHTML = recv_megs + "/" + size_megs + " MB";

      var uploadBar = document.getElementsByClassName("uploadBar", uploadProgress)[0];

      // calculate what the width of the progress bar should be, given the amount that has been transferred
      var newWidth = percent * 100;
      new Effect.ChangeWidth(uploadBar, newWidth, {transition:Effect.Transitions.linear, duration:3});
    }

    try {
      data = eval("(" + response.responseText + ")");
    } catch(e) {
      data = { 'state' : 'error', 'status' : 500 };
    }
    
    switch(data.state) {
      case 'done':
        UploadManager.uploadComplete(uploadKey);
        break;

      case 'uploading':
        update_the_page(data.received, data.size, data.received / data.size);
        break;
    }
  },

  uploadComplete: function(uploadKey) {

    // find out which form has just finished uploading
    var form = $("UploadForm_" + uploadKey);

    if (form) UploadManager.currentlyUploadingKey.pop(uploadKey)

    // get progress bar for the form that just finished then slide the bar to the end
    var uploadBar = document.getElementsByClassName("uploadBar", form)[0];
    new Effect.ChangeWidth(uploadBar, 100, {duration:1});

    // get the upload progress label and set it to "complete"
    var uploadLabel = document.getElementsByClassName("uploadProgressLabel", form)[0];
    new Effect.Rewriter(uploadLabel, "Completed", {queue: "end"});
    if (form) UploadManager.removeForm(form);

    UploadManager.checkForVideo(uploadKey, 0);

  },

  uploadFailed: function(uploadKey, overLimitFlag, message) {
    // find out which form has just finished uploading
    var form = $("UploadForm_" + uploadKey);

    if (!form) return

    UploadManager.currentlyUploadingKey.pop(uploadKey);
    UploadManager.removeForm(form);

    if (!opener) return;

    opener.$("OverLimitMessage").style.display = 'none';
    opener.$("OverCapMessage").style.display = 'none';
    opener.$("LockedMessage").style.display = 'none';

    if (overLimitFlag == "over limit") {
      opener.$("UploadButton").className = 'disabled';
      $("OverLimitAlert").style.display = 'block';
      opener.$("OverLimitMessage").style.display = 'block';

    } else if (overLimitFlag == "over cap") {
      opener.$("UploadButton").className = 'disabled';
      $("OverCapAlert").style.display = 'block';
      opener.$("OverCapMessage").style.display = 'block';

    } else if (overLimitFlag == "locked") {
      opener.$("UploadButton").className = 'disabled';
      $("LockedAlert").style.display = 'block';
      $$("#LockedAlert p")[0].innerHTML = message;
      opener.$("LockedMessage").style.display = 'block';
      opener.Warning.message(message, 0, true);
    }

  },

  checkForVideo: function(thisUploadKey, timesChecked) {

    if (timesChecked >= 3) {
      if (opener)
        opener.Warning.message("There was a problem with the last upload. You may need to try again.");
      return
    }

    // update the time remaining and the list of videos, but only if the window that opened this one still exists
    var updateVideoList = function() {
      if (opener.LibraryManager)
        setTimeout(function() { opener.LibraryManager.update() }, 3000)
    }

    // check to see if its ready
    var videoChecking = new Ajax.Request("/portal/check_for_video", {
      parameters: "upload_key=" + thisUploadKey,
      onSuccess: function(req) {
        if (req.responseText == "found")
          updateVideoList()
        else
          setTimeout(function() { UploadManager.checkForVideo(thisUploadKey, timesChecked + 1) }, 3000)
      },
      onFailure: SesameVaultError
    });

  },

  beginNextUpload: function() {

    var uploadingForms = document.getElementsByClassName("uploading");
    if (uploadingForms.length > 0) return false;

    // if there are any waiting upload forms then start the next one in the DOM
    var waitingForms = document.getElementsByClassName("waiting");
    if (waitingForms.length > 0) UploadManager.startUpload(waitingForms[0])

  },

  revealUploadProgress: function(uploadProgress) {

    new Effect.Appear(uploadProgress);

  },

  addNewForm: function() {

    var nodeToClone = $("CloneMe").firstChild;
    newestForm = nodeToClone.cloneNode(true);
    $("UploadForms").appendChild(newestForm);

    $$('#UploadForms input.uploadChooseFile').last().focus();

    // make the current upload forms sortable     FIXME
    //Sortable.create($("UploadForms"), {tag: "form", ghosting: true, constraint: false, overlap: "vertical"});

  },

  hideUploadButton: function(form) {

    chooseFile = document.getElementsByClassName("uploadChooseFile", form)[0];
    chooseFileButton = document.getElementsByClassName("chooseFileButton", form)[0];

    Element.setOpacity(chooseFile, 0);
    Element.setOpacity(chooseFileButton, 0);

  },

  cancelUpload: function(cancelButton) {

    // get the form that this cancel button belongs to
    form = cancelButton.parentNode.parentNode;

    if (form.hasAttribute("id")) {
      // extract the upload key from the id of the form element
      uploadKey = form.getAttribute("id").split("_")[1];

      // remove the upload key from the array of uploading video's keys
      UploadManager.currentlyUploadingKey.pop(uploadKey);
    }

    if (form) UploadManager.removeForm(form);

  },

  removeForm: function(thisForm) {

    // remove the div that blocks the text part of the input type="file" because it becomes visible when the drop out effect happens
    Element.hide(document.getElementsByClassName("ieChooseFileBlocker", thisForm)[0]);
    Element.hide(document.getElementsByClassName("chooseFileButton", thisForm)[0]);
    Element.hide(document.getElementsByClassName("uploadChooseFile", thisForm)[0]);

    Element.setStyle(thisForm, {zIndex:3});

    // drop out the form, delete it, then begin the next upload
    new Effect.DropOut(thisForm, {queue: "end", afterFinish: function() {
      Element.remove(thisForm);
      UploadManager.beginNextUpload();
    }})

  },

  displayFileName: function(form) {

    // get the filename... which is just after the last forward or backslash
    fileName = $A( form.getElementsByTagName("input")[0].value.split("/") ).last();
    fileName = $A( fileName.split("\\") ).last();

    // get span that contains the filename then set it
    fileNameEl = document.getElementsByClassName("fileName", form)[0];
    fileNameEl.innerHTML = fileName;

  },

  roundToHundredths: function(n) {
    ans = (Math.round(n * 100))/100 + ""
    dot = ans.indexOf(".",0)
    if (dot == -1) {ans = ans + ".00"}
    else if (dot == ans.length - 2) {ans = ans + "0"}
    return ans
  },

  launchUploadWindow: function(linkEl) {
    if(Element.hasClassName(linkEl, 'disabled')) return

    if (!UploadManager.uploadWindow || UploadManager.uploadWindow.closed)
      UploadManager.uploadWindow = window.open('/vault/upload', 'UploadWindow', 'width=520, height=300, scrollbars=yes, resizable=yes, toolbar=no, status=no, address=no, location=no, personalbar=no, directories=no')
    else
      UploadManager.uploadWindow.focus()

  },

  uploadWindow: false

};
