/*******************************************************************************
 * Topper
 * 
 * Imports:
 * 
 *   Asset
 *   Class
 *   Element
 *   Fx
 *   Options
 * 
 * Methods:
 * 
 *   none
 * 
 */



/*******************************************************************************
 * Classes
 */
var Topper = new Class({
  Implements: Options,
  options: {
    debug: false,
    href: "top",
    path: '/',
    percentage: 30,
    text: "Back to top",
    theme: "growl",
    title: "Go to the top of the page"
  },
  initialize: function(options) {
    // Merges the default options with the ones given as parameters
    this.setOptions(options);
    
    // Injects the stylesheet corresponding to the specified theme except in the
    // case a custom theme was provided throught external stylesheets  
    if (this.options.theme !== "custom") {
      // Updates the path according to the chosen theme
      this.options.path = this.options.path + "themes/" + this.options.theme;
      
      // Injects the CSS file of the theme inside the page
      Asset.css(this.options.path + "/styles.css");
    }
    
    // Builds the hash of the anchor
    var hash = '#' + this.options.href;
    
    // Creates the following template and injects it at the bottom of the page:
    // 
    //   <div class="topper">
    //     <a href="#top" title="Go to the top of the page">Back to top</a>
    //   </div>
    // 
    var container = new Element("DIV");
    container.addClass("topper");
    container.inject(document.body);
    
    var anchor = new Element('A');
    anchor.set("href", hash);
    anchor.set("text", this.options.text);
    anchor.set("title", this.options.title);
    anchor.inject(container);
    
    // Initializes visual effects
    var opacityEffect = new Fx.Tween(container, {property: "opacity", duration: 200, link: "cancel"});
    var scrollEffect = new Fx.Scroll(window);
    
    // Fixes positioning issue with Internet Explorer 6
    if (Browser.Engine.trident4) {
      container.setStyle("position", "absolute");
    }
    
    if (!this.options.debug) {
      // Hides the template at startup
      opacityEffect.set(0);
      
      // Changes the display of the template according to the position of the 
      // viewport (i.e. whether the user has already scrolled a certain amount
      // or not)
      window.addEvent("scroll", function(event) {
        if (this.isTooLow()) {
          opacityEffect.start(0.8);
        } else {
          opacityEffect.start(0);
        }
      }.bind(this));
    }
    
    // Enables smooth scrolling when the user clicks on the anchor
    anchor.addEvent("click", function(event) {
      // Stops event propagation (no other listener will ever get it)
      event.stop();
      
      // Moves the viewport back to the top of the page
      scrollEffect.toTop();
    });
    
    // Highlights the template when a custom theme was provided by acting on the
    // opacity
    if (this.options.theme === "custom") {
      container.addEvent("mouseover", function(event) {
        if (this.isTooLow()) {
          opacityEffect.start(1);
        }
      }.bind(this));
      
      container.addEvent("mouseout", function(event) {
        if (this.isTooLow()) {
          opacityEffect.start(0.8);
        }
      }.bind(this));
    }
  },
  isTooLow: function(options) {
    // Determines whether the viewport is too low, i.e. whether the user has
    // already scrolled a certain percentage of the viewport height
    return window.getScrollTop() > (window.getHeight() * this.options.percentage / 100);
  }
});