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.resizeElement();
    this.element.show();
  },

  hide: function() {
    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.50,
      zIndex:     this.options.zIndex || 1000
    });
  },

  resizeElement: function() {
    var dimensions = $(document.body).getDimensions();
    this.element.setStyle({
      width:  dimensions.width + "px",
      height: dimensions.height + "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 || 2000
    });

    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++;
    }
  }
};

document.observe("dom:loaded", function() {
  new DimZum.Controller({
    prefix: "sponsoredLinks",
    shade:  { background: "#fff" },
    window: { controls: $("sponsoredLinks_controls") }
  });

  new DimZum.Controller({
    prefix: "ecommerce",
    shade:  { background: "#fff" },
    window: { controls: $("ecommerce_controls") }
  });

  new DimZum.Controller({
    prefix: "digitalMarketingConsulting",
    shade:  { background: "#fff" },
    window: { controls: $("digitalMarketingConsulting_controls") }
  });

  new DimZum.Controller({
    prefix: "corporateSite",
    shade:  { background: "#fff" },
    window: { controls: $("corporateSite_controls") }
  });
});



