var Lightflow = {};

Lightflow = Class.create({
  initialize: function() {
    this.containerNode = $("lightflow");
    this._detectLinks();
    this._reflowLayout();
    this.containerNode.removeClassName("hidden_after_load")
  },
  
  show: function() {
    var sendEvent = this.containerNode.hasClassName("hidden");
    
    if (!this.containerNode.hasClassName("hidden_after_load")) {
      this.containerNode.removeClassName("hidden");
    }
    this._layout();
    window.scrollTo(0,0);
    
    if (sendEvent) this.containerNode.fire("lightflow:visible");
  },
  
  hide: function() {
    this.containerNode.addClassName("hidden");
  },
  
  isVisible: function() {
    return this.containerNode.getStyle("display") !== "none";
  },
  
  _detectLinks: function() {
    var self = this;
    $$("a[rel=lightflow]").each(function(link) {
      link.observe("click", function(event) {
        event.stop();
        self.load(event.element().getAttribute("href"));
      });
    });
  },
  
  _layout: function() {
    if (this.isVisible()) {
      var bodyHeight = $(document.body).getHeight();
      var lightflowContentHeight = this.containerNode.down(2).getHeight();
      if (lightflowContentHeight > bodyHeight)
        bodyHeight = lightflowContentHeight + 95; // in case the lightflow content height exceeds document body height (95 = lightflow top padding)
      
      this.containerNode.setStyle({height: bodyHeight + "px"});
      this.containerNode.down(1).setStyle({width: this.containerNode.down(2).getWidth() + "px"});
    }
    
    Event.observe(document.onresize ? document : window, "resize", this._layout.bind(this));
  },
  
  /**
   * Add custom actions to the opened lightflow view, like close button action and making the form use Ajax requests
   * instead of standard ones.
   */
  _addActions: function() {
    var self = this;
    this.containerNode.getElementsBySelector("a.close").each(function(closeButton) {
      closeButton.observe("click", function() {
        self.hide();
      });
    });
    
    // for links
    this.containerNode.getElementsBySelector("a.hide").each(function(closeButton) {
        closeButton.observe("click", function() {
          self.hide();
      });
    });
    
    // Treat enter keys as form submission - beware as it can be Ajax
    this.containerNode.getElementsBySelector("form[class!=standard] input").each(function(inputElement) {
      inputElement.observe("keydown", function(e) {
        if (e.keyCode == Event.KEY_RETURN) {
          e.stop();
          submitForm(inputElement.up("form"));
        }
      });
    });
    
    // Treat a.submit links as submit buttons
    this.containerNode.getElementsBySelector("form a.submit").each(function(submitElement) {
      var form = $(submitElement.up("form"));
      if (form.onsubmit) return;
      
      submitElement.stopObserving("click"); // prevents default action defined in Application._initializeUI
      $(submitElement).observe("click", function(event) {
        event.stop();
        event.element().writeAttribute("disabled", "disabled");

        submitForm(form, submitElement.hasClassName("file-upload"));
      });
    });
    
    // Submits a form via appropriate method
    var submitForm = function(form, hasFileUpload) {
      var pointsToNormalPage = form.hasClassName("standard");
      if (hasFileUpload || pointsToNormalPage) {
        form.submit();
      } else if (form.onsubmit) {
        form.onsubmit();
      } else {
        new Ajax.Updater('lightflow-container', form.readAttribute("action"), {
          method: form.readAttribute("method"),
          parameters: form.serialize(true),
          onComplete: function(transport) {
            self._reflowLayout();
            self.containerNode.fire("lightflow:updated");
          }
        });
      }
    };
  },
    
  _reflowLayout: function() {
    this.show();
    this._addActions();
    Application.focusFirstElement(true);
    Application.initOverlayedLabels(this.containerNode);
    
    if (Prototype.Browser.IE)
      this.containerNode.addClassName("forceLayout");
  }
});

Lightflow.init = function() {
  if (Lightflow.instance || !$("lightflow")) return;
  
  Lightflow.instance = new Lightflow();  
};

Lightflow.reinit = function() {
  Lightflow.instance = null;
  Lightflow.init();
};

Lightflow.load = function(url) {
  if ($("lightflow")) {
    Element.remove($("lightflow"));
  }
  
  new Ajax.Request(url, {
    method: "get",
    onComplete: function(transport) {
      $(document.body).insert({ bottom: transport.responseText });
      Lightflow.reinit();
      $("lightflow").fire("lightflow:loaded");
    }
  });
};

