var AnchorObserver = {
  enabled:  true,
  interval: 0.1
};

document.observe("dom:loaded", function() {
  var lastAnchor = "";

  function poll() {
    var anchor = (window.location.hash || "").slice(1);
    if (anchor != lastAnchor) {
      document.fire("anchor:changed", { to: anchor, from: lastAnchor });
      lastAnchor = anchor;
    }
  }

  if (AnchorObserver.enabled) {
    setInterval(poll, AnchorObserver.interval * 1000);
  }
});
(function() {
  var emptyAnchorHandler;
  function getEmptyAnchorHandler() {
    return emptyAnchorHandler = emptyAnchorHandler ||
      new Element("a").writeAttribute({
        name:       "/"
      }).setStyle({
        position:   "absolute",
        visibility: "hidden"
      });
  }

  document.observe("click", function(event) {
    var element = event.findElement("a[href=#/]");
    if (element) {
      var offsets = document.viewport.getScrollOffsets();
      $(document.body).insert(getEmptyAnchorHandler().setStyle({
        left: offsets.left + "px",
        top:  offsets.top + "px"
      }));
    }
  });
})();
Event.observe(window, "resize", function(event) {
  document.fire("viewport:resized");
});

var DimZum = {
  Version: "0.1"
};

DimZum.Controller = Class.create({
  initialize: function(options) {
    this.options = options || { };
    this.prefix  = options.prefix || "z";
    this.active  = false;

    document.observe("anchor:changed", this.onAnchorChanged.bind(this));
    document.observe("shade:clicked", this.onShadeClicked.bind(this));
    document.observe("viewport:resized", this.onViewportResized.bind(this));
    document.observe("keypress", this.onKeyPressed.bind(this));
  },

  getShade: function() {
    return this.shade = this.shade || new DimZum.Shade(this.options.shade);
  },

  getWindow: function() {
    return this.window = this.window || new DimZum.Window(this.options.window);
  },

  onAnchorChanged: function(event) {
    if (this.isActableAnchor(event.memo.to)) {
      var elements = this.getElementsFromAnchor(event.memo.to);
      this.showElement(elements.first());

    } else {
      this.hideActiveElement();
    }
  },

  onShadeClicked: function(event) {
    this.close();
  },

  onViewportResized: function(event) {
    if (this.active) {
      this.getShade().resizeElement();
      this.getWindow().repositionWindow();
    }
  },

  onKeyPressed: function(event) {
    if (this.active && event.keyCode == Event.KEY_ESC) {
      this.close();
      event.stop();
    }
  },

  isActableAnchor: function(anchor) {
    if (anchor && anchor.substring(0, this.prefix.length + 1) == this.prefix + "/")
      return this.getElementsFromAnchor(anchor).first();
  },

  getElementsFromAnchor: function(anchor) {
    return anchor.substring(this.prefix.length + 1).split("/").map(function(id) { return $(id) });
  },

  showElement: function(element) {
    if (!this.active) this.getShade().show();
    this.getWindow().showWithContents(element);
    this.active = true;
  },

  hideActiveElement: function() {
    if (this.active) {
      this.getWindow().hide();
      this.getShade().hide();
      this.active = false;
    }
  },

  close: function() {    
    window.location.hash = "#/";
    this.hideActiveElement();
  },

  clearPurgatory: function() {
    this.getWindow().clearPurgatory();
  }
});
DimZum.Shade = Class.create({
  initialize: function(options) {
    this.options = options || { };
    this.createElement();
    $(document.body).insert(this.element);
    this.element.observe("click", this.onClick.bind(this));
  },

  show: function() {
    this.hideSelectBoxes();
    this.resizeElement();
    this.element.show();
  },

  hide: function() {
    this.showSelectBoxes();
    this.element.hide();
  },

  createElement: function() {
    this.element = new Element("div").hide();
    this.element.setStyle({
      position:   "absolute",
      top:        0,
      left:       0,
      background: this.options.background || "#000",
      opacity:    this.options.opacity || 0.5,
      zIndex:     this.options.zIndex || 9999
    });
  },

  getPageSize: function(){
      var xScroll, yScroll;

      if (window.innerHeight && window.scrollMaxY) {
              xScroll = document.body.scrollWidth;
              yScroll = window.innerHeight + window.scrollMaxY;
      } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
              xScroll = document.body.scrollWidth;
              yScroll = document.body.scrollHeight;
      } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
              xScroll = document.body.offsetWidth;
              yScroll = document.body.offsetHeight;
      }

      var windowWidth, windowHeight;
      if (self.innerHeight) {	// all except Explorer
              windowWidth = self.innerWidth;
              windowHeight = self.innerHeight;
      } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
              windowWidth = document.documentElement.clientWidth;
              windowHeight = document.documentElement.clientHeight;
      } else if (document.body) { // other Explorers
              windowWidth = document.body.clientWidth;
              windowHeight = document.body.clientHeight;
      }

      // for small pages with total height less then height of the viewport
      if(yScroll < windowHeight){
              pageHeight = windowHeight;
      } else {
              pageHeight = yScroll;
      }

      // for small pages with total width less then width of the viewport
      if(xScroll < windowWidth){
              pageWidth = windowWidth;
      } else {
              pageWidth = xScroll;
      }


      arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
      return arrayPageSize;
  },

 showSelectBoxes: function (){
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}
  },

  // ---------------------------------------------------

  hideSelectBoxes: function(){
          selects = document.getElementsByTagName("select");
          for (i = 0; i != selects.length; i++) {
                  selects[i].style.visibility = "hidden";
          }
  },



  resizeElement: function() {
    var dimensions = $(document.body).getDimensions(); // nao funciona em certos casos de css do site
    var arrayPageSize = this.getPageSize();
    this.element.setStyle({
      width:  dimensions.width + "px",
      //height: dimensions.height + "px"
      height: arrayPageSize[1] + "px"
      //width:  arrayPageSize[0] + "px"
    });
  },

  onClick: function(event) {    
    this.element.fire("shade:clicked", { shade: this });
  }
});
DimZum.Window = Class.create({
  initialize: function(options) {
    this.options = options || { };
    this.createElements();
  },

  createElements: function() {
    if (this.options.element) {
      this.element  = this.options.element;
      this.viewport = this.element.down("div.viewport");

    } else {
      this.element  = new Element("div").hide();
      this.viewport = new Element("div").addClassName("viewport");
      this.controls = this.options.controls ||
        new Element("div").update('<a href="#/">Close</a>');

      this.element.insert(this.viewport);
      this.controls.show().addClassName("controls");
      this.element.insert(this.controls);
    }

    this.element.addClassName(this.options.className || "dim_zum_window");
    this.element.setStyle({
      position: "absolute",
      top:      0,
      left:     0,
      zIndex:   this.options.zIndex || 99999
    });

    this.purgatory = new Element("div").hide();

    $(document.body).insert(this.element);
    $(document.body).insert(this.purgatory);
  },

  showWithContents: function(contentElement) {
    this.adoptContents(contentElement);
    this.repositionWindow();
    this.element.show();
  },

  adoptContents: function(contentElement) {
    this.releaseContents();
    this.viewport.insert(contentElement);
    this.hasContents = true;
    contentElement.show();
  },

  getContents: function() {
    if (this.hasContents)
      return this.viewport.down();
  },

  releaseContents: function() {
    var contents = this.getContents();
    if (contents) {
      contents.hide();
      this.purgatory.insert(contents);
    }

    this.hasContents = false;
  },

  repositionWindow: function() {
    var windowDimensions   = this.element.getDimensions();
    var viewportDimensions = document.viewport.getDimensions();
    var viewportOffsets    = document.viewport.getScrollOffsets();

    var xOffsetFactor = this.options.xOffset || 0.5;
    var yOffsetFactor = this.options.yOffset || 0.5;

    var left = viewportDimensions.width * xOffsetFactor - windowDimensions.width * xOffsetFactor;
    var top  = viewportDimensions.height * yOffsetFactor - windowDimensions.height * yOffsetFactor;

    this.element.setStyle({
      left: viewportOffsets.left + left + "px",
      top:  viewportOffsets.top + top + "px"
    });
  },

  hide: function() {
    this.releaseContents();
    this.element.hide();
  },

  clearPurgatory: function() {
    this.purgatory.update("");
  }
});
var ExtraExtra = {
  count: 0,

  DateHelper: {
    timeAgoInWords: function(from) {
      return this.distanceOfTimeInWords(new Date(), from);
    },

    distanceOfTimeInWords: function(to, from) {
      var distance_in_seconds = ((to - from) / 1000);
      var distance_in_minutes = (distance_in_seconds / 60).floor();

      if (distance_in_minutes <= 0)      return "less than a minute";
      if (distance_in_minutes == 1)      return "a minute";
      if (distance_in_minutes < 45)      return distance_in_minutes + " minutes";
      if (distance_in_minutes < 90)      return "about 1 hour";
      if (distance_in_minutes < 1440)    return "about " + Math.round(distance_in_minutes / 60) + " hours";
      if (distance_in_minutes < 2880)    return "1 day";
      if (distance_in_minutes < 43200)   return Math.round(distance_in_minutes / 1440) + " days";
      if (distance_in_minutes < 86400)   return "about 1 month";
      if (distance_in_minutes < 525960)  return Math.round(distance_in_minutes / 43200) + " months";
      if (distance_in_minutes < 1051199) return "about 1 year";

      return "over " + (distance_in_minutes / 525960).floor() + " years";
    }
  },

  register: function(element) {
    element = $(element);
    this.relativizeTimeIn(element);
    this.setVisibilityOf(element);
  },

  relativizeTimeIn: function(container) {
    var element = container.down(".relative_time");
    if (element) {
      var time = new Date(element.readAttribute("time"));
      element.update(ExtraExtra.DateHelper.timeAgoInWords(time));
    }
  },

  setVisibilityOf: function(element) {
    var container = element.up(".extra_extra_news");
    if (container) {
      var count = parseInt(container.readAttribute("count"));
      if (count && this.count >= count) element.hide();
      this.count++;
    }
  }
};
