/**
*
* PageScroller
*
* Bucket of things related to scrolling, from event handling to UI response
*
*/

// constants for readability
var FORWARD = 1
var BACK	 = -1

var SCROLL_FX_DURATION = 500 // in millis

var onload_scroll = null // proc that can be defined by individual pages
var next_page = null
var prev_page = null

var PageScroller = {
  last_page_num: 1, // !
  current_page_num: null,
  scroll_fx: null,
  
  init: function() {
    // set up MooTools scroller
    if (!disable_column_wrapper) {
      this.scroll_fx = new Fx.Scroll('horizsheet', {
    		wait: false,
    		duration: SCROLL_FX_DURATION,
    		transition: Fx.Transitions.Quad.easeInOut
    	})
    	this.current_page_num = 1
  	}
  	
  	// set up -/+ links
  	$('forward').addEvent('click', function(event) {
  		event = new Event(event).stop()
  		PageScroller.scroll(FORWARD)
  	})
  	$('back').addEvent('click', function(event) {
  		event = new Event(event).stop()
  		PageScroller.scroll(BACK)
  	})
  	
  	// ...with keyboard support
  	document.addEvent('keydown', function(e) {
      e = new Event(e) // .stop() // oops don't stop, we might want that!
      if (e.key == 'right') {
        PageScroller.scroll(FORWARD)
        PageScroller.flicker_page_turn('forward')
      } else if (e.key == 'left') {
        PageScroller.scroll(BACK)
        PageScroller.flicker_page_turn('back')
      }
    })
    
    // set up progress dots
    if (!disable_column_wrapper && !disable_subnav) {
      var page_scroller = this;
      for (var i=1; i<=ColumnWrapper.num_pages; i++) {
        $('page_progress').adopt(new Element('a', {
          'href': '#',
          'id': 'progress_dot_'+i,
          'events': {
            'click': function(e) {
              e = (new Event(e)).stop();
              this.blur();
              var to_page = new RegExp(/\d+/).exec(this.id);
              page_scroller.set_current_page_num(parseInt(to_page));
              page_scroller.do_scroll();
            }}}).adopt(new Element('img', {'src': '/images/spacer.gif', 'width': '8', 'height': '8'})));
      }
    }
    
    this.init_hide_hidden_hack()
    
    if (onload_scroll) onload_scroll() // defined by individual pages
    
    this.do_scroll() // init +/-
  },
  
  /**
  * Factored this out so that when we change the element's 'title' we can re-generate the tips.
  * TODO: need to be able to wipe out previous tips (for now, they linger, even if the UI element is ghosted)
  */
  refresh_tips: function() {
    $$('.pageturn').each(function(scroll_link) {
      new Tips(scroll_link, {
        fixed: true,
        className: scroll_link.id + "-tip", // so we can do CSS directly. had to mod busted Tips plugin.
        showDelay: 200,
        hideDelay: 200,
        onShow: function(tip) {
          (new Fx.Tween(tip, {property: 'opacity', duration: 200})).start(0.6)
        },
        onHide: function(tip) {
          (new Fx.Tween(tip, {property: 'opacity', duration: 200})).start(0.0)
        }
      });
    });
  },
  
  /**
  * Relative scrolling function (fwd/bck)
  * if we're at beginning/end, go to previous/next story
  * FIXME. hard-coding next piece links!
  */
  scroll: function(direction) {
    switch (direction) {
      case FORWARD:
        if (this.current_page_num < ColumnWrapper.num_pages) this.set_current_page_num(this.current_page_num + 1)
        else if (next_page) window.location = next_page.url
        break
      case BACK:
        if (this.current_page_num > 1) this.set_current_page_num(this.current_page_num - 1)
    	  else if (prev_page) window.location = prev_page.url
        break
    }
  	this.do_scroll()
  },
  
  /**
  * Currently only works if element is top-level (as this version of MooTools has no getParents(), ugh)
  */
  scroll_to_element: function(element_id) {
    var scroll_to_page = $(element_id).getParent().getParent();
    var page_num_matches = scroll_to_page.id.match(/page(\d+)/);
    if (page_num_matches && page_num_matches.length) {
			this.set_current_page_num(parseInt(page_num_matches[1]));
			this.do_scroll();
		}
  },
  
  /**
  * the actual call to Fx.Scroll, and update icons.
  * this.current_page_num must already be set before we enter this function.
  */
  do_scroll: function() {
    this.do_hide_hidden_hack()
    
    if (this.scroll_fx) this.scroll_fx.toElement('page'+this.current_page_num)
    
    this.update_scroll_icon('forward', next_page, ColumnWrapper.num_pages, "&rarr;")
    this.update_scroll_icon('back', prev_page, 1, "&larr;")
    
    this.refresh_tips()
    
    // update progress dots
    if (!disable_column_wrapper && !disable_subnav) {
      var page_counter = 1
      var current_page_num = this.current_page_num
      $$('#page_progress a').each(function(el) {
        if ((page_counter++) == current_page_num) el.addClass('current')
        else el.removeClass('current')
      }) 
    }
  },
  
  /**
  * Some browsers let hidden content peek through in certain circumstances, namely Flash players in FireFox
  * (see: http://jonathanleighton.com/blog/flash-z-index-bug-firefox) and elements positioned in a certain
  * way in IE7 (in the TOC). So we do this dance of showing/hiding them on scroll events.
  *
  * This is getting cluttered with legacy logic, must simplify old piece HTML. 
  */
  init_hide_hidden_hack: function() {
    if (Browser.Engine.gecko && $('vimeopage')) $('vimeopage').setStyle('display', 'none')
    if (Browser.Engine.trident) $$('.hide_scroll').setStyle('display', 'none')
  },
  do_hide_hidden_hack: function() {
    if (Browser.Engine.trident) {
      $('page'+this.current_page_num).getElements('.hide_scroll').each(function(el) {
        setTimeout(function() {el.setStyle('display', 'block')}, SCROLL_FX_DURATION)
      })
      $('page'+this.last_page_num).getElements('.hide_scroll').each(function(el) {
        el.setStyle('display', 'none')
      })
    }
    if (Browser.Engine.gecko) {
      if ($('page'+this.current_page_num) && $('page'+this.current_page_num).hasChild($('vimeopage'))) {
        setTimeout(function() {
          $('vimeopage').setStyle('display', 'block')
        }, SCROLL_FX_DURATION)
      } else if ($('page'+this.last_page_num) && $('page'+this.last_page_num).hasChild($('vimeopage'))) {
        $('vimeopage').setStyle('display', 'none')
      }
    }
  },
  
  /**
  * update -/+ to indicate navigation status, including tooltip text.
  * The CSS class logic is getting pretty crazy in here.
  * (relevant css classes for #back/#forward: pageturn, ghost, jump (& flicker))
  */
  update_scroll_icon: function(icon_id, link_to_page, boundary_page_num, action_key) {
    var tip_title = icon_id // cheap!
    var tip_body = "or use the <br/><span style='font-size: 120%'>"+action_key+"</span> key"
    if (!this.current_page_num || this.current_page_num == boundary_page_num) {
      if (link_to_page) { // display link to next/prev story
        tip_title = "to <b>" + link_to_page.title + "</b>"
        $(icon_id).addClass('pageturn').addClass('jump')
      } else { // disable icon link!
        $(icon_id).removeClass('pageturn').addClass('ghost')
        tip_title = tip_body = ""
      }
    } else { // flipping through pages in one story
      $(icon_id).addClass('pageturn').removeClass('jump').removeClass('ghost')
    }
    $(icon_id).store('tip:title', tip_title).store('tip:text', tip_body);
  },
  
  /**
  * if user navs with keyboard, give visual feedback to explain what's up
  */
  flicker_page_turn: function(link_id) {
    $(link_id).addClass('flicker')
    setTimeout(function() {
      $(link_id).removeClass('flicker')
    }, SCROLL_FX_DURATION/2)
  },
  
  set_current_page_num: function(current_page_num) {
    this.last_page_num = this.current_page_num
    this.current_page_num = current_page_num
  }
}
