Element.implement({
  isVisible: function() {  
    return this.getStyle('display') != 'none';
  },
  toggle: function() {  
    return this[this.isVisible() ? 'hide' : 'show']();
  },
  hide: function() {  
    this.originalDisplay = this.getStyle('display');
    this.setStyle('display','none');
    return this;
  },
  show: function(display) {  
    this.originalDisplay = (this.originalDisplay=="none")?'block':this.originalDisplay;
    this.setStyle('display', (display || this.originalDisplay || 'block'));
    return this;
  },
  dwindle: function () {  
    var element = this;
    new Fx.Morph(element, {
      duration: 600,
      onComplete: function () {      
        element.remove();
      }
    }).start({
      'opacity': 0,
      'width': 0,
      'height': 0
    });
  }
});

Window.implement({
	$E: function(selector){
		return this.document.getElement(selector);
	}
});

var i = null;
var nowt = '';
window.addEvent('domready', function() {
  i = new Interface();
  i.activate();
});

var Interface = new Class({
  initialize: function() {  
    this.nav = null;
    this.tabsets = {};
    this.banners = [];
    this.galleries = [];
  },
  activate: function () {  
    this.findNav();
    this.findTabs();
    this.findBanners();
    this.findGalleries();
    this.findExpandables();
  },
  findNav: function () { 
    this.nav = new NavBar( $E('div#navigation') );
  },
  findTabs: function () { 
    $$('a.tab').each(function (a) { new Tab(a); });
  },
  findBanners: function () { 
    $$('a.banner').each( function (element) { new BannerAd(element); }); 
  },
  findGalleries: function () { 
    $$('div.gallery').each( function (element) { this.galleries.push( new Gallery(element) ); }, this); 
  },
  findExpandables: function () { 
    $$('input.has_expansion').each( function (element) { new Expandable(element); }); 
  },
  killEvent: function (e) {
    if (e) {
      if (e.target) e.target.blur();
      var event = new Event(e);
      if (event) {
        event.preventDefault();
        event.stop();
      }
    }
  }
});

var NavBar = new Class({
  initialize: function (element) {    
    this.div = element;
    this.opento = this.div.getHeight();
    this.closeto = 23;
    this.timer = null;
    var nb = this;
    this.openFX = new Fx.Tween(this.div, {
      'property': 'height',
      'duration': 'normal',
      'transition': 'bounce:out',
      'onStart': function () {        
        nb.div.addClass('open');
        nb.state = 'opening';
      },
      'onComplete': function () {        
        nb.state = 'open';
      }
    });
    this.closeFX = new Fx.Tween(this.div, {
      'property': 'height',
      'duration': 'long',
      'transition': 'cubic:out',
      'onStart': function () {        
        nb.state = 'closing';
      },
      'onComplete': function () {        
        nb.div.removeClass('open');
        nb.state = 'closed';
      }
    });
    this.closeFX.set(this.closeto);
    this.state = 'closed';
    this.div.setStyle('visibility', 'visible');
    var openbar = this.open.bindWithEvent(this);
    var closebar = this.close.bindWithEvent(this);
    var closebarsoon = this.closeSoon.bindWithEvent(this);
    var cancelclose = this.cancelClose.bindWithEvent(this);
    this.div.addEvent('mouseenter', openbar);
    this.div.addEvent('mouseleave', closebarsoon);
    $$('a.hidenav').each(function (a) {      
      a.onclick = closebar;
    });
    $$('a.shownav').each(function (a) {      
      a.onmouseover = openbar;
      a.onmouseout = closebarsoon;
    });
  },
  open: function (e) {    
    this.cancelClose(e);
    if (this.state.contains('clos')) {      
      if (this.state == 'closing') this.closeFX.cancel();
      this.openFX.start(this.opento);
    }
  },
  close: function (e) {    
    if (this.state.contains('open')) {      
      if (this.state == 'opening') this.openFX.cancel();
      this.closeFX.start(this.closeto);
    }
  },
  closeSoon: function (e) {    
    var nb = this;
    this.timer = (function () { nb.close(e); }).delay(1500);
  },
  cancelClose: function (e) {      
    var event = i.killEvent(e);
    $clear(this.timer);
  }
});

var Tab = new Class({
	initialize: function(element){
		this.tabhead = element;
		this.name = this.tabhead.get('text');
    var parts = element.id.split('_');
		this.tag = parts.pop();
		this.settag = parts.pop();
		this.tabbody = $E('#' + this.settag + '_' + this.tag);
    this.tabset = i.tabsets[this.settag] || new TabSet(this.settag);
    this.tabset.addTab(this);
 		this.tabhead.onclick = this.select.bindWithEvent(this);
	},
	select: function (e) {
    i.killEvent(e);
	  this.tabhead.blur();
    this.tabset.select(this);
	},
  show: function(){
    this.tabhead.addClass('fg');
    this.tabbody.addClass('fg');
  },
  hide: function(){
    this.tabbody.removeClass('fg');
    this.tabhead.removeClass('fg');
  }
});

var TabSet = new Class({
	initialize: function(tag){
	  this.tabs = [];
    this.tag = tag;
    this.foreground = null;
 		i.tabsets[this.tag] = this;
	},
	addTab: function (tab) {
    this.tabs.push(tab);
    if (this.tabs.length == 1) {
      tab.show();
      this.foreground = tab;
    } else {
      tab.hide();
    }
	},
	select: function (tab) {
	  this.tabs.each(function (t) { 
	    if (t.tag == tab.tag) {
	      t.show();
	      this.foreground = t;
	    } else {
        t.hide();
	    }
	  }, this);
	},
  next: function (tab) {
    if (!tab) tab = this.foreground;
    var i = this.tabs.indexOf(tab);
    return (i == this.tabs.length-1) ? this.tabs[0] : this.tabs[i+1];
  },
  previous: function (tab) {
    if (!tab) tab = this.foreground;
    var i = this.tabs.indexOf(tab);
    return (i == 0) ? this.tabs.getLast() : this.tabs[i-1];
  },
  showNext: function (e) { 
		i.closeEvent(e);
    this.select(this.next()); 
  },
  showPrev: function (e) { 
		i.closeEvent(e);
    this.select(this.previous()); 
  },
	play: function () {},
	stop: function () {}
});













var BannerAd = new Class({
  initialize: function (element) {    
    this.background = element;
    this.foreground = element.getElement('img');
    this.background.addEvent('mouseenter', this.up.bindWithEvent(this));
    this.background.addEvent('mouseleave', this.down.bindWithEvent(this));
    this.down();
  },
  up: function() {    
    this.foreground.setStyle('opacity', 1);
  },
  down: function() {    
    this.foreground.fade(0.25);
  }
});

var Gallery = new Class({
  initialize: function (element) { 
    this.container = element;   
    this.shower = this.container.getElement('.gallery_shower');
    this.captioner = this.container.getElement('.gallery_caption');
    this.wrapper = this.container.getElement('.gallery_wrapper');
    this.main_link = new Element('a').inject(this.shower);
    this.showing = new Element('img').inject(this.main_link);
    this.revert_message = this.captioner.get('text');

    this.scroller = new Fx.Scroll(this.wrapper, {transition: Fx.Transitions.Cubic.easeOut, duration: 'long', onComplete: this.showPageLinks.bind(this)});
    this.transitionOut = new Fx.Tween(this.showing, {property: 'opacity', onComplete: this.preloadNextItem.bind(this)});
    this.transitionIn = new Fx.Tween(this.showing, {property: 'opacity', onComplete: this.explainItem.bind(this)});
    
    this.pages = [];
    this.container.getElements('ul.gallery_page').each(function (element) { this.pages.push(new GalleryPage(element, this)); }, this);

    if (this.pages.length > 0) {
      this.first_page = this.pages[0];
      this.last_page = this.pages[this.pages.length - 1];
    
      this.current_page = this.first_page;
      this.current_item = null;
      this.next_item = null;

      this.page_lefter = this.container.getElement('a.gallery_left');
      this.page_righter = this.container.getElement('a.gallery_right');

      this.links_holder = new Element('div', {'class': 'gallery_links'}).inject(this.shower);
      this.image_lefter = new Element('a', {'class': 'item_left', 'href': '#'}).inject(this.links_holder);
      this.downloader = new Element('a', {'class': 'item_download', 'href': '#', 'target': '_blank'}).inject(this.links_holder);
      this.image_righter = new Element('a', {'class': 'item_right', 'href': '#'}).inject(this.links_holder);

      this.image_lefter.onclick = this.showPreviousItem.bindWithEvent(this);
      this.image_righter.onclick = this.showNextItem.bindWithEvent(this);
      this.page_lefter.onclick = this.moveLeft.bindWithEvent(this);
      this.page_righter.onclick = this.moveRight.bindWithEvent(this);

      this.showPageLinks();
      this.preloader = null;
      
      // var first_slide = this.find_item_with_id(window.location.hash) || this.current_page.first_item;
      // first_slide.showMe();

      this.current_page.first_item.showMe();
      
      // alert(this.showing.getStyle('z-index'));
      // alert(this.links_holder.getStyle('z-index'));

    }
  },
  pageBefore: function (page) {
    if (!page) page = this.current_page;
    if (page == this.first_page) return this.last_page; 
    if (page && this.pages.contains(page)) return this.pages[this.pages.indexOf(page)-1];
    return this.last_page;
  },
  pageAfter: function (page) {
    if (!page) page = this.current_page;
    if (page == this.last_page) return this.first_page;
    if (page && this.pages.contains(page)) return this.pages[this.pages.indexOf(page)+1];
    return this.first_page;
  },
  moveLeft: function (e) {
    i.killEvent(e);
  	this.showPage(this.pageBefore());
  },
  moveRight: function (e) {
    i.killEvent(e);
  	this.showPage(this.pageAfter());
  },
  showPage: function (page) {
    if (page != this.current_page) {
    	this.scroller.toElement(page.container);
      this.current_page = page;
    }
  },
  showPageLinks: function () {
    if (this.pages.length == 1) {
      this.page_lefter.setStyle('visibility', 'hidden');
      this.page_righter.setStyle('visibility', 'hidden');
    } else {
      if (this.current_page == this.last_page) this.page_righter.addClass('right_end');
      else  this.page_righter.removeClass('right_end');
      if (this.current_page == this.first_page) this.page_lefter.addClass('left_end');
      else  this.page_lefter.removeClass('left_end');
    }
  },
  showPreviousItem: function (e) {
    i.killEvent(e);
    this.current_item.previousItem().showMe();
  },
  showNextItem: function (e) {
    i.killEvent(e);
    this.current_item.nextItem().showMe();
  },
  showItem: function (item) {     // this should not be called directly. call item.showMe() to hit page and item triggers properly.
    if (item != this.current_item) {
      this.next_item = item;
      this.hideItem();
    }
  },
  hideItem: function () {
    if (this.current_item) this.current_item.unHighlightMe();
    this.say(nowt);
    this.links_holder.hide();
    this.transitionOut.start(0);
  },
  preloadNextItem: function () {
    fadeup = this.finishShowItem.bind(this);
    this.preloader = new Asset.image(this.next_item.preview_url, {onload : fadeup});
  },
  finishShowItem: function () {     // called by onload of next_item preview image in loadAndThen
    this.showing.set('src', this.preloader.get('src'));
    this.downloader.set('href', this.next_item.download_url);
    this.main_link.set('href', this.next_item.download_url);
    this.current_item = this.next_item;
    this.next_item = null;
    this.current_item.highlightMe();
    this.transitionIn.start(1);
  },
  explainItem: function () {     // called by onComplete of transitionIn tween
    this.say(this.current_item.caption);
    this.links_holder.setStyles({
      'left': this.showing.getLeft() - this.shower.getLeft(), 
      'width': this.showing.getWidth(), 
      'height': this.showing.getHeight()
    });
    this.links_holder.show();
    // this.links_holder.setStyle('background-color', '#d1005d');
  },
  say: function (message) {
    this.revert_message = this.captioner.get('text');
    this.captioner.set('text', message);
  },
  unsay: function (message) {
    this.captioner.set('text', this.revert_message);
  }
});

var GalleryPage = new Class({
  initialize: function (element, gallery) {    
    this.container = element;
    this.gallery = gallery;
    this.items = [];
    this.container.getElements('li.gallery_item').each(function (element) { this.items.push(new GalleryItem(element, this)); }, this);
    this.first_item = this.items[0];
    this.last_item = this.items[this.items.length-1];
    this.current_item = null;
  },
  showMe: function (e) {
    i.killEvent(e);
    this.gallery.showPage(this);
  },
  showItem: function (item) {
    this.showMe();
    this.current_item = item;
    this.gallery.showItem(item);
  },
  previousPage: function () {
    return this.gallery.pageBefore(this);
  },
  nextPage: function () {
    return this.gallery.pageAfter(this);
  },
  itemBefore: function (item) {
    if (!item) item = this.current_item;
    if (item == this.first_item) return this.previousPage().last_item;
    if (item && this.items.contains(item)) return this.items[this.items.indexOf(item)-1];
    return this.last_item;
  },
  itemAfter: function (item) {
    if (!item) item = this.current_item;
    if (item == this.last_item) return this.nextPage().first_item;
    if (item && this.items.contains(item)) return this.items[this.items.indexOf(item)+1];
    return this.first_item;
  }
});

var GalleryItem = new Class({
  initialize: function (element, gallerypage) {    
    this.icon = element.getElement('img');
    this.id = element.get('id');
    this.clicker = element.getElement('a.gallery_preview');
    this.preview_url = this.clicker.get('href');
    this.download_url = element.getElement('a.gallery_download').get('href');
    this.caption = element.getElement('span').get('html');
    this.page = gallerypage;
    this.gallery = gallerypage.gallery;
    this.clicker.onclick = this.showMe.bindWithEvent(this);
    this.borderFX = new Fx.Tween(this.icon, {property: 'border-color'});
  },
  showMe: function (e) {
    i.killEvent(e);
    this.page.showItem(this);
  },
  showCaption: function (e) {
    i.killEvent(e);
    this.gallery.say(this.caption);
  },
  hideCaption: function (e) {
    i.killEvent(e);
    this.gallery.unsay(this.caption);
  },
  previousItem: function () {
    return this.page.itemBefore(this);
  },
  nextItem: function () {
    return this.page.itemAfter(this);
  },
  highlightMe: function () {
    this.borderFX.start('#868e8d');
  },
  unHighlightMe: function () {
    this.borderFX.start('#ffffff');
  }
});

var Expandable = new Class ({
  initialize: function (element) {    
    this.stub = element;
    this.expansion = $E('p#' + this.stub.id + '_expansion');
    this.field = this.expansion.getElement('input');
    this.stub.onclick = this.showif.bindWithEvent(this);
    this.showif();
  },
  showif: function (e) {
    this.stub.checked ? this.show() : this.hide();
  },
  show: function() {    
    this.expansion.show();
    this.field.focus();
  },
  hide: function() {    
    this.expansion.hide();
  }
});


