/*globals window, document, RSVP, rJS, Handlebars,
         location, console*/
/*jslint indent: 2, maxlen: 80*/
(function (window, document, RSVP, rJS, Handlebars, location, console) {
  "use strict";

  var CODE_CONTENT_KEY = "text_content";

  function getExtension(url) {
    var extension = url.split('.').pop();
    if (extension.endsWith('/')) {
      return ".html";
    }
    return "." + extension;
  }

  function createJio(gadget, jio_config) {
    var jio_gadget;
    return gadget.getDeclaredGadget("jio_gadget")
      .push(function (jio_g) {
        jio_gadget = jio_g;
        if (jio_config === undefined)
          jio_config = {type: "indexeddb", database: "cribjs"};
        console.log(jio_config);
        return jio_gadget.createJio(jio_config);
    });
  }

  function createDAVJio(gadget, event) {
    return createJio(gadget, {
      type:"dav",
      url: gadget.props.element.querySelector('.form-use-jio-dav .url').value,
      basic_login: btoa(gadget.props.element.querySelector(".form-use-jio-dav .credential").value)
    });
  }  
  
  function displayURLList(gadget, event) {
    return new RSVP.Queue()
    .push(function () {
       return gadget.getDeclaredGadget('crib_sw_gadget');
    })
    .push(function (crib_sw_gadget) {
       return crib_sw_gadget.allDocs();
    })
    .push(function(data) {
      var contentsElement = gadget.props.element.querySelector('.crib-url-list-content tbody'),
        footer_element = gadget.props.element.querySelector('.crib-url-list-content tfoot'),
        url_list = data.urls,
        url_number = 0, cached_number = 0,
        url, trElement, tdElement;
      // Clear out the existing items from the list.
      while (contentsElement.firstChild) {
        contentsElement.removeChild(contentsElement.firstChild);
      }
      console.log(url_list);
      // Add each cached URL to the list, one by one.
      for (url in url_list) {
        if (url_list.hasOwnProperty(url)) {
          var element;
          cached_number = url_list[url].cached ? cached_number + 1 : cached_number;
          url_number += 1;
          trElement = document.createElement('tr');
          tdElement = document.createElement('td');
          tdElement.innerHTML = (url_list[url].cached ? "<span>&#x2713;</span>" : "")
          trElement.appendChild(tdElement);
          tdElement = document.createElement('td');
          element = document.createElement('a');
          element.setAttribute('href', "#view=editor&url=" + url);
          element.textContent = url;
          tdElement.appendChild(element);
          trElement.appendChild(tdElement);
          tdElement = document.createElement('td');
          element = document.createElement('a');
          element.textContent = "Go";
          element.setAttribute('href', url);
          element.setAttribute('target', "_blank");
          element.setAttribute("class", "btn btn-primary btn-xs");
          tdElement.appendChild(element);
          trElement.appendChild(tdElement);
          contentsElement.appendChild(trElement);
        }
      };
      while (footer_element.firstChild) {
        footer_element.removeChild(footer_element.firstChild);
      }
      trElement = document.createElement('tr');
      tdElement = document.createElement('td');
      tdElement.innerHTML = "<span>" + cached_number + " &#x2713;</span>";
      trElement.appendChild(tdElement);
      tdElement = document.createElement('td');
      tdElement.innerHTML =  url_number + " URLs";
      trElement.appendChild(tdElement);      
      tdElement = document.createElement('td');
      trElement.appendChild(tdElement);
      footer_element.appendChild(trElement);
    })
    .fail(function(error) {
      // XXX An Error Should be thrown
      console.log(error);
      throw error;
    });
  }

  function saveTextContent(gadget, event) {
    var content,
      url = gadget.props.element.querySelector("form.crib-editor-get .url").value,
      mimetype = gadget.props.element.querySelector("form.crib-editor-save .mimetype").value;
    console.log("saving content");
    return new RSVP.Queue()
    .push(function () {
       return gadget.getDeclaredGadget('codeeditor');      
     })
    .push(function (code_editor_gadget) {
       return code_editor_gadget.getContent();
    })
    .push(function (data) {
       content = data[CODE_CONTENT_KEY] || "";
       return gadget.getDeclaredGadget('crib_sw_gadget');
    })
    .push(function (crib_gadget) {
       return crib_gadget.put(url, {content:content, type:mimetype});
    })
    .push(function() {
      gadget.props.element.querySelector(".crib-editor-save-status").textContent = "Saved " + url + " files at "+ Date ()
    })
    .fail(function(error) {
      console.log(error);
      gadget.props.element.querySelector(".crib-editor-save-status").textContent = error;
    });
  }

  function getUrlTextContent(gadget, event, url) {
    console.log("saving content");
    return new RSVP.Queue()
    .push(function () {
      return gadget.getDeclaredGadget('crib_sw_gadget');
    })
    .push(function (crib_gadget) {
      return RSVP.all([crib_gadget.get(url),
        gadget.getDeclaredGadget('codeeditor')])
    })
    .push(function(data_list) {
      //gadget.props.element.querySelector("form.crib-editor-save .content").value = data_list[0].responseText;
      gadget.props.element.querySelector("form.crib-editor-save .mimetype").value = data_list[0].responseType;
      return data_list[1].render({
        key: CODE_CONTENT_KEY,
        value: data_list[0].responseText,
        mode: data_list[0].responseType
        });
    })
    .fail(function(error) {
      console.log(error);
    });
  }

  function saveContentToJIO(gadget, event) {
    var path_to_save, path_to_save_length, application_id, crib_sw_gadget,
      jio_gadget, url_list = [], saved_number = 0;
    path_to_save = gadget.props.element.querySelector('form.crib-save-to-jio .save-path').value
    application_id = gadget.props.element.querySelector('form.crib-save-to-jio .save-id').value
    path_to_save_length = path_to_save.length;
    return new RSVP.Queue()
    .push(function () {
      return RSVP.all([
        gadget.getDeclaredGadget('crib_sw_gadget'),
        gadget.getDeclaredGadget('jio_gadget')]);
    })
    .push(function (gadget_list) {
      crib_sw_gadget = gadget_list[0];
      jio_gadget = gadget_list[1];
      return crib_sw_gadget.allDocs({cached_only: true});
    })
    .push(function(data) {
      url_list = data.urls;
      // This is buggy, it fails if the document already exists with dav storage
      return RSVP.all(
        [jio_gadget.put("/" + application_id + ".attachment/", {
                 // url: path_to_save
                  }),
         jio_gadget.putAttachment("/", application_id, new Blob([JSON.stringify({url: path_to_save})],{type: "application/json"}))  
      ]);      
    })
    .push(function() {
      var promise_list = [],
        i, i_len, url;
      for (i = 0, i_len = url_list.length; i < i_len; i += 1) {
        url = new String(url_list[i]);
        if (url.indexOf(path_to_save) === 0) {
          saved_number += 1;
          promise_list.push(jIO.util.ajax({
            url: url,
            dataType: "blob"
            }));
        };
      };
      return RSVP.all(promise_list);
    })
    .push(function(response_list) {
      var promise_list = [],
        i, i_len, url, response, extension;
      for (i = 0, i_len = response_list.length; i < i_len; i += 1) {
        response = response_list[i];
        url = response.target.responseURL.substr(path_to_save_length)
        extension = getExtension(url)
        console.log("Will push attachment " + url + " to " + path_to_save);
        promise_list.push(
          jio_gadget.putAttachment("/" + application_id + ".attachment/", btoa(url) + extension,
            response.target.response
          )
        );
      };
      return RSVP.all(promise_list)
    })
    .push(function() {
      gadget.props.element.querySelector(".crib-save-to-jio-status").textContent = "Saved " + saved_number + " files at "+ Date ()
    })
    .fail(function(error) {
      gadget.props.element.querySelector(".crib-save-to-jio-status").textContent = error;
      console.log(error);
    });
  }


  function loadContentFromJIO(gadget, event) {
    var path_to_load, path_to_load_length, application_id, crib_sw_gadget,
      jio_gadget, url_list = [];
    path_to_load = gadget.props.element.querySelector('form.crib-load-from-jio .load-path').value
    application_id = gadget.props.element.querySelector('form.crib-load-from-jio .load-id').value
    path_to_load_length = path_to_load.length;
    return new RSVP.Queue()
    .push(function () {
      return RSVP.all([
        gadget.getDeclaredGadget('crib_sw_gadget'),
        gadget.getDeclaredGadget('jio_gadget')]);
    })
    .push(function (gadget_list) {
      crib_sw_gadget = gadget_list[0];
      jio_gadget = gadget_list[1];
      return jio_gadget.allAttachments("/" + application_id + ".attachment/");
    })
      .push(function(response) {
        var promise_list = [],
          key, extension;
        for (key in response) {
          if (response.hasOwnProperty(key)) {
            extension = getExtension(key);
            console.log(key);
            url_list.push(atob(key.substr(0, key.length - extension.length)))
            promise_list.push(jio_gadget.getAttachment("/" + application_id + ".attachment/", key));
          }
        };
        return RSVP.all(promise_list)
      })
      .push(function(response_list) {
        var promise_list = [],
          i, i_len, url, index, response, location, location_len;
        location = document.location.origin;
        location_len = location.length
        console.log(url_list);
        console.log(response_list);
        for (i = 0, i_len = response_list.length; i < i_len; i += 1) {
          url = url_list[i]
          index = url.indexOf(location);
          if (index != -1)
            url = url.substr(index + location_len);
          promise_list.push( 
            crib_sw_gadget.put(path_to_load + url, {blob: response_list[i]})
          )
        }
      })
      .push(function() {
        gadget.props.element.querySelector(".crib-load-from-jio-status").textContent = "Loaded " + url_list.length + " files at "+ Date ()
      })
    .fail(function(error) {
      gadget.props.element.querySelector(".crib-load-from-jio-status").textContent = error;
      console.log(error);
    });
  }

  function massRemoveFromCache(gadget, event) {
    var url_list = gadget.props.element.querySelector("form.crib-mass-remove textarea").value.match(/[^\r\n]+/g),
      url_list_length = url_list.length;
    return new RSVP.Queue()
    .push(function () {
      return gadget.getDeclaredGadget('crib_sw_gadget');
    })
    .push(function (crib_gadget) {
      var i,
        promise_list = [];
      for (i = 0; i < url_list_length; i += 1) {
        console.log(url_list[i])
        promise_list.push(crib_gadget.remove(url_list[i]));
      };
      return RSVP.all(promise_list);
    })
    .push(function() {
      gadget.props.element.querySelector(".crib-mass-remove-status").textContent = "Removed " + url_list.length + " files at "+ Date ()
    })
    .fail(function(error) {
      gadget.props.element.querySelector(".crib-mass-remove-status").textContent = error;
      console.log(error);
    });
  }

  function displayTabContent(gadget, state) {
    var tab_content_list = gadget.props.element.querySelectorAll('.nav_content');
    console.log(tab_content_list.length);
    for (var i = 0; i < tab_content_list.length; i += 1 ){
      console.log('working with:');
      console.log(tab_content_list[i]);
      if (tab_content_list[i].getAttribute('class').indexOf(state) === -1) {
        tab_content_list[i].setAttribute('style', 'display:none;');
      } else {
        tab_content_list[i].setAttribute('style', '');
      }
    }
  }

  rJS(window)
    .ready(function (g) {
      g.props = {};
      return g.getElement()
        .push(function (element) {
          g.props.element = element;
         });
    })
    .ready(function (g) {
      return createJio(g);
    })
    .allowPublicAcquisition("editor_saveContent", function () {
      return saveTextContent(this, undefined);
    })
    .declareMethod('render', function (options) {
      var promise_list = [],
        gadget = this;
      gadget.props.element.querySelector('form.crib-save-to-jio .save-path').value = document.location.origin;
      gadget.props.element.querySelector('form.crib-load-from-jio .load-path').value = document.location.origin;
      gadget.props.options = options;
      // Add promise for list Cache content
      if (options.url !== undefined) {
        gadget.props.element.querySelector("form.crib-editor-get .url").value = options.url;
        promise_list.push(getUrlTextContent(gadget, undefined, options.url))
      }
      displayTabContent(gadget, options.view || 'cribjs');
      promise_list.push(displayURLList(gadget, undefined));
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".crib-url-list-content"),
        'submit',
        false,
        function (event) {displayURLList(gadget, event)}
      ));
      // promise to get content from URL
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".crib-editor-get"),
        'submit',
        false,
        function (event) {
          var url = gadget.props.element.querySelector("form.crib-editor-get .url").value;
          return getUrlTextContent(gadget, event, url);
        }
      ));
      // promise to save content
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".crib-editor-save"),
        'submit',
        false,
        function (event) {saveTextContent(gadget, event)}
      ));
      // promise to save content to jIO
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".crib-save-to-jio"),
        'submit',
        false,
        function (event) {saveContentToJIO(gadget, event)}
      ));
      // promise to load content from jIO
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".crib-load-from-jio"),
        'submit',
        false,
        function (event) {loadContentFromJIO(gadget, event)}
      ));
      // promise to remove content from cache
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".crib-mass-remove"),
        'submit',
        false,
        function (event) {massRemoveFromCache(gadget, event)}
      ));
      // promise to use dav storage for jIO
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".form-use-jio-dav"),
        'submit',
        false,
        function (event) {createDAVJio(gadget, event)}
      ));
      // promise to use local storage for jIO
      promise_list.push(loopEventListener(
        gadget.props.element.querySelector(".form-use-jio-local"),
        'submit',
        false,
        function (event) {createJio(gadget, {type: "indexeddb", database: "cribjs"})}
      ));
      return RSVP.all(promise_list);
    })


}(window, document, RSVP, rJS, Handlebars, location, console));