var lDialogs = {
  params: {
    content:     null,  // Element or String
    target:      null,  // String
    opacity:     0.5,    
    title:       null,  // Element or String
    width:       null,  // Int, Optional
    height:      null,  // Int, Optional
    className:   null,  // Classname to add to the content div
    close: {
      link:      true,
      overlay:   false,
      esc:       true
    },
    ajax: {
      url:       null,
      options:   {},    // Ajax Updater options
      resize:    [0,0]  // [width:int, height:int]
    },
    afterOpen:   Prototype.emptyFunction, // function
    beforeClose: Prototype.emptyFunction,  // function
    afterClose:  Prototype.emptyFunction  // function
  },
  emptyElement:  function() {
    return new Element("div").update("No content/target/ajax specified.");
  },
  lastDialog:    null   // holds a reference to the last LDialog
  
};

var LDialog = Class.create({
  
  // Instance Variables:
  // elementOverlay      :div
  // elementContainer    :div
  // elementHeader       :div
  // elementCloseButton  :div
  // elementContent      :div
  // elementTitleText    :span
  // beforeClose         :Function
  // afterClose          :Function
  // boundKeypressMethod :Function
  
  initialize: function(o) {
        
    var params   = Object.extend(Object.clone(lDialogs.params), o || {});
    params.close = Object.extend(Object.clone(lDialogs.params.close), o.close || {});
    //console.log(params);
    
    var elementOverlay = new Element("div", {"id": "dialogOverlay"});
    elementOverlay.setOpacity(params.opacity);
    if (params.close.overlay) elementOverlay.observe("click", this.close.bind(this));
    $(document.body).insert(elementOverlay);
    
    var elementContainer = new Element("div", {"id": "dialogContainer"});
    $(document.body).insert(elementContainer);
    
    var elementCloseButton;
    if (params.close.link) {
      elementCloseButton = new Element("div", {"id": "dialogCloseButton"}).observe("click", this.close.bind(this));
      elementContainer.insert(elementCloseButton);
    };
    
    if (params.close.esc) {
      this.boundKeypressMethod = this.doKeyPress.bind(this);
      document.observe('keypress', this.boundKeypressMethod);
    };
    
    var elementContent = new Element("div", {"id": "dialogContent"});
    if (params.width)     elementContent.setStyle({width:  params.width  + "px"});
    if (params.height)    elementContent.setStyle({height: params.height + "px"});
    if (params.className) elementContent.addClassName(params.className);
    
    if (params.content) {
      elementContent.update(params.content);
    } else if (params.target) {
      var target = $(params.target);
      if (target) {
        elementContent.update(target.innerHTML);
      } else {
        elementContent.update(lDialogs.emptyElement());
      }
    } else {
      elementContent.update(lDialogs.emptyElement());
    }
    
    if (o.ajax) {
      if (o.ajax.url) {
        this.updateContentViaAjax(o.ajax);
      }
    }
    
    var elementHeader;
    var elementTitleText;
    if (params.title || params.close.link) {
      elementHeader = new Element("div", {"id": "dialogHeader"});
      elementTitleText = new Element("span", {"id": "dialogHeaderText"}).insert(params.title);
      elementHeader.insert(elementTitleText);
      elementContainer.insert(elementHeader);
    };
    elementContainer.insert(elementContent);
    
    if (elementHeader)      this.elementHeader      = elementHeader;
    if (elementCloseButton) this.elementCloseButton = elementCloseButton;
    if (elementTitleText)   this.elementTitleText   = elementTitleText;
    this.elementOverlay     = elementOverlay;
    this.elementContainer   = elementContainer;
    this.elementContent     = elementContent;
    
    this.resize();
    lDialogs.lastDialog = this;
    
    if (Object.isFunction(params.beforeClose)) this.beforeClose = params.beforeClose;
    if (Object.isFunction(params.afterClose)) this.afterClose = params.afterClose;
    if (Object.isFunction(params.afterOpen)) params.afterOpen();
    
    return this;
  },
  updateContentViaAjax: function(o) {
    
    var params     = Object.extend(Object.clone(lDialogs.params.ajax), o);
    params.options = Object.extend(Object.clone(lDialogs.params.ajax.options), o.options || {});
    
    var ajaxParams = params.options;
    
    var w = params.resize[0];
    var h = params.resize[1];
    
    if (Object.isFunction(ajaxParams.onComplete)) {
      ajaxParams.onComplete = ajaxParams.onComplete.wrap(
        function() {
          var args = $A(arguments), callOriginal = args.shift();
          this.resize(w,h);
          callOriginal();
        }
      ).bind(this);
    } else {
      ajaxParams.onComplete = this.resize.curry(w,h).bind(this);
    }
    new Ajax.Updater("dialogContent", params.url, ajaxParams);
    
  },
  resize: function(w,h) {
    
    if (w && w != 0) this.elementContent.setStyle({width:  w  + "px"});
    if (h && h != 0) this.elementContent.setStyle({height: h  + "px"});
        
    var dims = this.elementContainer.getDimensions();
    this.elementContainer.setStyle({
      marginLeft: "-" + parseInt(dims.width  * 0.5, 10) + "px",
      marginTop: "-" + parseInt(dims.height * 0.5, 10) + "px"
    });
  },
  close: function(e) {
    
    if (this.beforeClose) this.beforeClose();
    
    this.removeListeners();
    this.removeElements();
    
    if (this.afterClose) this.afterClose();
    if (lDialogs.lastDialog === this) lDialogs.lastDialog = null;
  },
  removeElements: function() {
    if (this.elementCloseButton) this.elementCloseButton.remove();
    if (this.elementTitleText) this.elementTitleText.remove();
    if (this.elementHeader) this.elementHeader.remove();
    this.elementContent.remove();
    this.elementContainer.remove();
    this.elementOverlay.remove();
  },
  removeListeners: function() {
    if (this.elementCloseButton) this.elementCloseButton.stopObserving();
    this.elementOverlay.stopObserving();
    if (this.boundKeypressMethod) document.stopObserving('keypress', this.boundKeypressMethod);
  },
  updateTitle: function(title) {
    if (!this.elementHeader) {
      this.elementHeader = new Element("div", {"id": "dialogHeader"});
      this.elementTitleText = new Element("span", {"id": "dialogHeaderText"}).update(title);
      this.elementHeader.insert(this.elementTitleText);
      this.elementContainer.insert({top:this.elementHeader});
    } else {
      this.elementTitleText.update(title);
    }
    this.resize();
  },
  updateContent: function(element) {
    this.elementContent.update(element);
    this.resize();
  },
  // updateContentHideOld, Updates the contents of the dialog without destroying the existing content
  updateContentHideOld: function(element) {
	this.elementContent.childElements().invoke('hide');
    this.elementContent.insert(element);
    this.resize();
  },
  clearSizing: function() {
    this.elementContent.setStyle({height:"", width:""});
    this.resize();
  },
  doKeyPress: function(e) {
    if (e.keyCode == Event.KEY_ESC) this.close(e);
  }
});


LDialog.close = function(){
	if (lDialogs.lastDialog != null){
		lDialogs.lastDialog.close();
	}
}

LDialog.resize = function(){
	if (lDialogs.lastDialog != null){
		lDialogs.lastDialog.resize();
	}
}
