/**
 * @depends prototype.js
 * @depends effects.js
 * @depends slider.js
 * @depends g-ext.js
 * @depends loader.js
 */

var Toolbar = Class.create({
	
  initialize: function(container, options) {
    this.options = Object.extend({
      timeout: 1.5
    }, options || {});
    this.container = container;
    this.active = false;
    this.animating = false;
    this.visible = false;
    this.hider = null;
    this.container.insert(this.toolbar = this.build());
    this.registerEvents();
  },
  build: function(){
    return new Element('div', { className: 'toolbar' }).update(
      '<a href="#next" class="next" rel="nextPage">' + Gucci.getTerm('catalog_nextpage') + '</a>'+
      '<span class="position" id="toolbar_position"> </span>'+
      '<a href="#prev" class="previous" rel="previousPage">' + Gucci.getTerm('catalog_prevpage') + '</a>'+
      '<a href="#index" class="index" rel="showIndex">' + Gucci.getTerm('catalog_index') + '</a>'+
      '<a href="#close" class="close" rel="returnToThumbnails">' + Gucci.getTerm('catalog_home') + '</a>'
    ).setStyle({
      opacity: 0,
      display: 'none'
    });
  },
  registerEvents: function(){
    document.observe('state:active', this.show.bindAsEventListener(this));
    document.observe('state:idle', this.dim.bindAsEventListener(this));
    this.container.observe('toolbar:activate', this.activate.bindAsEventListener(this));
    this.container.observe('toolbar:deactivate', this.deactivate.bindAsEventListener(this));
    this.container.observe('toolbar:busy', this.busy.bindAsEventListener(this));
    this.container.observe('toolbar:idle', this.idle.bindAsEventListener(this));
    this.container.observe('toolbar:update', this.update.bindAsEventListener(this));
    
    this.toolbar.select('a[href]').each(function(link){
      link.observe('click', function(event){
        event.stop();
        this.container.fire('toolbar:clicked', { action: link.readAttribute('rel') });
      }.bind(this));
    }.bind(this));
  },
  update: function(event){
    $('toolbar_position').update(event.memo.currentPage + '/' + event.memo.totalPages);
  },
  show: function(){
    if(!this.active) return;
    if(this.visible || this.animating) return;
    Effect.Queues.get('toolbar').invoke('cancel');
    this.toolbar.show().morph('opacity: .65', { 
      duration: .5, 
      queue:{ scope: 'toolbar' }, 
      beforeStart: function(){ this.animating = true; }.bind(this),
      afterFinish: function(){ this.visible = true; this.animating = false; }.bind(this)
    });
  },
  dim: function(event){
    // Don't hide toolbar if the mouse pointer is on it
    if(event && event.memo.location[0] >= 0 && event.memo.location[0] <= this.toolbar.getWidth() && 
    event.memo.location[1] >= 0 && event.memo.location[1] <= this.toolbar.getHeight())
      return;
    
    Effect.Queues.get('toolbar').invoke('cancel');
    this.visible = false;
    this.toolbar.morph('opacity: 0', { duration: 2, queue:{ scope: 'toolbar' } });
  },
  hide: function(){
    Effect.Queues.get('toolbar').invoke('cancel');
    if(Prototype.Browser.IE)
      this.toolbar.hide();
    else
      this.toolbar.morph('opacity: 0', { duration: 0.25, queue:{ scope: 'toolbar' } });
  },
  activate: function(e){
    if(this.active) return;
    this.active = true;
    this.show();
    this.onInterruptEvent = this.onInterrupt.bindAsEventListener(this);
    this.container.observe('mousemove', this.onInterruptEvent);
    this.onInterrupt(e);
  },
  deactivate: function(){
    this.active = false;
    this.animating = false;
    this.visible = false;
    this.hide();
    this.container.stopObserving('mousemove', this.onInterruptEvent);
  },
  busy: function(){
    this.toolbar.addClassName('busy');
  },
  idle: function(){
    this.toolbar.removeClassName('busy');
  },
  onInterrupt: function(event){
    var localPointer = Event.localPointer(event, this.toolbar);
    document.fire('state:active', { idleTime: new Date() - this._idleTime });
		clearTimeout(this._timer);
		this._idleTime = new Date();
		this._timer = setTimeout(function() {
			document.fire('state:idle', { location: localPointer });
		}, this.options.timeout * 1000);
  }

});

var Catalog = Class.create({
  
  EMPTY_IMG: '/images/empty.gif',
  catalogWidth: 762,
  containerWidth: 1235,
  initialize: function(snippet, options) {
    this.loopEl    = $$('body')[0];
    this.rootEl    = $('container'); // We need to resize that element in order to keep things layed out
    this.catalog   = $(snippet);
    this.buildCatalog();
    
    this.data = _catalog_pages || {};
    this.texts = _catalog_texts[options.lang] || {};
    this.styles = $H(_catalog_data) || {};
    this.totalPages  = this.data.pages.size();
    this.id        = options.id;
    this.isCatalog = true;

    // Converting data.pages objects to hash adding page numbers
    this.data.pages.each(function(page, iterator){
      page.pageNum = iterator;
    });
    // Extending catalog structure with texts
    $A(['title', 'links']).each(function(property){
      this.data[property] = this.texts[property];
    }.bind(this));
    Object.extend(this.data.intro, this.texts.intro);
    this.texts.pages.each(function(page, iterator){
      var currentPage = page.pageNum - 1;
      delete(page.pageNum);
      Object.extend(this.data.pages[currentPage], page);
    }.bind(this));
   
    this.titlePage = this.data.intro || null;
    this.textPages = this.data.pages.findAll(function(page){ return page.type == 'text' || page.type == 'title'; });

    // createing allThumbs
    this.allThumbs = this.data.pages.select(function(value) {
      return !$A(this.textPages).include(value);
    }.bind(this));

    this.thumbCount = this.data.intro ? 4 : 6;
    this.thumbClass = 'thumb';
    if ((this.allThumbs.size()<this.thumbCount) ||
        (this.loopEl.hasClassName('catalog-small')) ||
        (this.loopEl.hasClassName('catalog-small-intro')))  {
      this.thumbCount=1;
      this.thumbClass = 'thumb single';
      if (!this.titlePage) {
        this.catalogWidth = 506;
        this.containerWidth = 978;
      }
       
    }
    /* Initial state */
    this.currentPage = 1;
    this.originalWidths = {
      catalog: this.catalog.getWidth(),
      rootEl: this.rootEl.getWidth()
    };
    
    this.buildHTML();
    
    new Toolbar(this.container);
    this.container.observe('toolbar:clicked', function(event){
      var proc = eval('this.' + event.memo.action + '.bind(this)');
      proc.call();
    }.bind(this));
    
    this.catalog.delegate('click', {
      '.catalog-home .title, .catalog-title a.open': function(event){ 
        event.stop(); 
        this.selectThumbnail(0, true); 
      }.bind(this),
      '.catalog-home .thumb': function(event){
        var pageNum = event.findElement('.catalog-home .thumb').readAttribute('rel');
        if(pageNum < 0) return;
        this.selectThumbnail(pageNum, true);
      }.bind(this),
      '.catalog-index .clickable': function(event){
        var indexEl = this.catalog.down('.catalog-index');
        var pageNum = event.findElement('.catalog-index .clickable').readAttribute('rel');
        indexEl.removeClassName('active');
        this.selectThumbnail(pageNum, false);
      }.bind(this),
      '.catalog-page .page': function(event){
        var page = event.findElement('.page');
        var localX = Event.localPointer(event, page)[0];
        if(localX < parseInt(page.getWidth() / 2,10))
          this.previousPage();
        else
          this.nextPage();
      }.bind(this)
    });

    if ($('logo') != null && typeof getCookie == 'function') {
  		var durl = document.URL;
  		var begin, end, prefix;
  		begin = durl.indexOf('://');
  		if(begin != -1) {
    			begin += 3;
    			end = durl.indexOf('/', begin);
    			if(end != -1) {
      			prefix = 'http://' + unescape(durl.substring(begin, end));
    			}
  		}

  		if (Engine.isMSIE) {
  			$('logo').replace('<div id="logo" style="text-indent: 0; filter: none; background: none;"><a href="' + prefix + '/' + getCookie('site') + '/"><img src="/images/gucci-logo.gif" width="164" height="30" alt="gucci"></a></div>');
  		}
  		else {
      		Event.observe('logo','click',function(){ 
  				document.location = prefix + '/' + getCookie('site') + '/';
  			});
  			$('logo').setStyle({cursor:'pointer'});
  		}
    }
  },
  
  buildCatalog: function(){
    
    //Main catalog struture
    this.catalog.update('<div class="catalog-container"><div class="catalog-page"></div></div><div class="catalog-index"> </div>');
    // Catalog home page
    if (this.thumbCount!=1)
      this.catalog.insert({'bottom': '<div class="catalog-home small"><div class="pages"></div><div class="catalog-title"></div><ol class="links-list"> </ol></div>'});
    else
      this.catalog.insert({'bottom': '<div class="catalog-home small"><div class="pages"></div><div class="catalog-title"></div><ol class="links-list"> </ol></div>'});
    
    // Info panel HTML
    this.catalog.insert({'bottom': '<div class="catalog-panel"><div class="details"><ol class="links-list"></ol><div class="scroller-container"><div class="style_list_top"></div><ol class="style-list"></ol><div class="style_list_bottom"></div><div class="scrollbar" style="display: none"><div class="handle"></div></div></div></div></div>'});
    
    this.container = this.catalog.down('.catalog-container');
    this.pagesContainer = this.catalog.down('div.pages');
  },
  
  buildHTML: function(){
    this.linkTmp = new Template('<li><a href="#{url}" title="#{name}">#{name}</a></li>');
    this.styleTmp = new Template('<li><span>#{description}</span><em class="sku">#{sku}</em><em class="price">' + Gucci.getTerm('price-template') + '</em></li><br />');
	this.styleNoPriceTmp = new Template('<li><span>#{description}</span><em class="sku">#{sku}</em></li><br />');
    
    // Building title section
    this.catalog.down('.catalog-title').update('<h1><a href="#open" class="open">' + this.data.title.gsub(/\'/, "&rsquo;") + '</a></h1><p class="info"><a href="#open" class="open">' + Gucci.getTerm('catalog_open') + '</a></p>');
    
    // Building links section
    var linksList = this.catalog.down('.links-list').update();
    this.data.links.each(function(obj){
      linksList.insert({'bottom': this.linkTmp.evaluate(obj)});
    }.bind(this));
    
    // Building title page element
    if(this.titlePage) {
      this.pagesContainer.insert(
        new Element('div', {
          className: 'title'
        }).setStyle({
          'backgroundColor': this.titlePage.textBg,
          'color': this.titlePage.textColor
        }).insert(this.prepareText(this.titlePage.abstractHTML))
      );
    }
    
    this.thumbPages = [];
    var remaining = this.thumbCount;
    
    (this.thumbCount).times(function(idx){
      this.thumbPages.push(idx);
      
        var src = (this.allThumbs[idx]) ? this.allThumbs[idx].thumb : this.EMPTY_IMG;
      
      Loader.load(src, { 
        onComplete:function(src){
          var thumbnail = new Element('div', { className: this.thumbClass, rel: (this.allThumbs[idx]) ? this.allThumbs[idx].pageNum : '-1' }).update(
            new Element('img', { src: src })
          ).setOpacity(0);
          
          this.pagesContainer.insert(thumbnail);
          thumbnail.appear();
          
          remaining--;
          if(remaining == 0)
           this.startRotate();
        }.bind(this)
      });
    }.bind(this));
  },
  
  buildTextLayer: function(page){
    var pageData  = this.data.pages[page];
    var global = this.data.intro || {};
    
    if(Object.isUndefined(pageData)) return;
    
    if(pageData.textHTML) {
      var textEl = new Element('div', { className: 'page-text' });
      var textpanel = new Element('div', {
          className: pageData.textClassName
        });
      if (pageData.textBg)  
        textpanel.setStyle({
          backgroundColor: pageData.textBg, 
          color: pageData.textColor || global.textColor
        }).insert(this.prepareText(pageData.textHTML));
      else
        textpanel.setStyle({
          color: pageData.textColor || global.textColor
        }).insert(this.prepareText(pageData.textHTML));
      
      return textEl.update(textpanel);
    }
    else 
      return '';
  },
  
  prepareText: function(text){
    return text.stripScripts().strip().gsub(/\b([A-Z][A-Z0-9]{2,})\b/, function(match){ return '<abbr>' + match[0] + '</abbr>'; });
  },

  reverseText: function(text){
	return text.split('').reverse().join(''); 
  },

  addPriceCommas: function(price){
	price = price.toString();
	return this.reverseText(this.reverseText(price).replace(/(\d\d\d)(?=\d)(?!\d*\.)/g,'$1,'));
  },
  
  selectThumbnail: function(page, fadeIn) {
    var page = parseInt(page,10);
    var container = this.container;
    var pageData  = this.data.pages[page];
    var imageUrl = pageData.hires || this.EMPTY_IMG;
    new Effect.Appear(container, {
      from: fadeIn ? 0 : 1,
      to: 1,
      duration: fadeIn ? 1 : 0,
      beforeStart: function(fx){
        this.stopRotate();
        container.setOpacity(fadeIn ? 0 : 1).addClassName('active').down('.catalog-page').update('<p class="loader">Loading...</p>');
      }.bind(this),
      afterFinish: function(fx){
        // Do expand animation only once
        if(!this.catalog.hasClassName('expanded'))
          new Effect.Parallel([
            this.catalog.resize(780, {sync: true}),
            this.rootEl.resize(1252, {sync: true})
          ], {
            afterUpdate: function(){ document.fire('layout:changed'); },
            afterFinish: function(){
              this.catalog.addClassName('expanded').scrollTo(); // For small resolutions scroll to viewport
            }.bind(this)
          });
        
        // Loading image
        Loader.load(imageUrl, { 
          onComplete: function(image){
            this.currentPageEl = new Element('div', { className: 'page' }).update(
              new Element('img', { src: imageUrl })
            ).insert(this.buildTextLayer(page));
            
            container.down('.catalog-page').insert(this.currentPageEl);
            this.currentPage = page;
            container.fire('toolbar:update', { currentPage: page + 1, totalPages: this.totalPages });
            
            this.animatePage({
              effect: fadeIn,
              onComplete: function(){
                container.removeClassName('busy');
                container.fire('toolbar:activate');
                
                this.updatePanel(this.styles.get(page+1));
              }.bind(this)
            });
          }.bind(this)
        });
      }.bind(this)
    });
  },
  
  showIndex: function(event){
    var container = this.container;
    var indexEl = this.catalog.down('.catalog-index');
    var totalIndexPages = this.data.pages.size();
    
    var grid = 3;
    if(totalIndexPages > 9) grid = 4;
    if(totalIndexPages > 16) grid = 5;
    
    this.catalog.down('.catalog-home').hide();
    container.fire('toolbar:deactivate');
    this.currentPageEl = null;
    
    this.hidePanel({
      onComplete: function(){
        new Effect.Fade(container, {
          duration: 1,
          beforeStart: function(){
            container.removeClassName('active');
            indexEl.hide().addClassName('active grid-' + grid);
          },
          afterFinish: function(){
            var thumbsel='.catalog-index .thumbnail img';
            if (container.id)
              thumbsel = '#' + container.id + ' ' + thumbsel; // indexEl.getElementByClassName does not work on Safari
            var thumbs = $$(thumbsel); 
            
            if (thumbs.length==0) {
              (grid*grid).times(function(idx){
              
                var lastrowClass = (idx >= grid*(grid-1)) ? ' lastrow' : '';
              
                thumbs[idx] = new Element('img', { src:'/images/empty.gif' });
                var thumb = new Element('div', { 
                  className: 'thumbnail' + lastrowClass, 
                  rel: this.data.pages[idx] ? this.data.pages[idx].pageNum : '-1'
                }).update(new Element('span')).insert(thumbs[idx]).insert(this.buildTextLayer(idx));

                indexEl.insert(thumb);
              }.bind(this));
            }
            
			if (totalIndexPages > 25) totalIndexPages = 25;
            var remaining = totalIndexPages;
            totalIndexPages.times(function(idx){
              var img = thumbs[idx];
              var src = this.data.pages[idx].thumb ? this.data.pages[idx].thumb : this.EMPTY_IMG;

              Loader.load(src, {
                onComplete: function(){
                  img.up().addClassName('clickable');
                  // Applying bilinear interpolation for resized images in IE6
                  if(Prototype.Browser.IE6)
                    img.setStyle("filter: progid:DXImageTransform.Microsoft.AlphaImageLoader (src='" + src + "', sizingMethod='scale');");
                  else
                    img.src = src;
                    
                  remaining--;
                  if(remaining == 0) indexEl.appear({duration: Prototype.Browser.IE6 ? 0 : 1});
                }
              });
            }.bind(this));

          }.bind(this)
        });
        
      }.bind(this)
    });
  },
  
  showSpinner: function(){
    this.busy = true;
    this.container.fire('toolbar:busy');
  },
  
  hideSpinner: function(){
    this.busy = false;
    this.container.fire('toolbar:idle');
  },
  
  nextPage: function(){
    if(this.busy) return;
    this.currentPage++;
    if(this.currentPage >= this.totalPages) this.currentPage = 0;
    this.moveToPage(this.currentPage, 1);
  },
  
  previousPage: function(){
    if(this.busy) return;
    this.currentPage--;
    if(this.currentPage < 0) this.currentPage = this.totalPages - 1;
    this.moveToPage(this.currentPage, -1);
  },
  
  moveToPage: function(page, pos){
    var page = parseInt(page,10);
    this.showSpinner();
    this.updatePanel(this.styles.get(page+1));
    var src = this.data.pages[page].hires || this.EMPTY_IMG;
    var container = this.container.down('.catalog-page');
    this.container.addClassName('busy');
    
    Loader.load(src, { 
      onComplete: function(src) {
   
        var directionClassName = (pos > 0) ? 'dir-right' : 'dir-left';        
        var newPageEl = new Element('div', { className: 'page ' + directionClassName });
        newPageEl.setStyle({
          width: '0px',
          opacity: 0,
          backgroundImage: 'url('+src+')'
        });
        
        newPageEl.insert(new Element('img', { src: '/images/empty.gif' }));
		if (!Prototype.Browser.IE6)
			newPageEl.insert(this.buildTextLayer(page, directionClassName));
			
        container.insert(newPageEl);
        
        this.currentPage = page;

        container.fire('toolbar:update', { currentPage: page + 1, totalPages: this.totalPages });
        
        newPageEl.morph('width: 780px; opacity: 1', { 
          duration: 1.4, 
          afterFinish: function() {
			if (Prototype.Browser.IE6)
				newPageEl.insert(this.buildTextLayer(page, directionClassName));
			
            if(this.currentPageEl) this.currentPageEl.remove();
            this.currentPageEl = newPageEl;
            newPageEl.down('img').writeAttribute({src: src});
            
            this.container.removeClassName('busy');
            
            this.container.fire('toolbar:activate');
            this.hideSpinner();
            
          }.bind(this)
        });
      }.bind(this)
    });
  },
  
  returnToThumbnails: function(){
    this.hidePanel({
      onComplete: function(){
        new Effect.Parallel([
          this.catalog.resize(this.catalogWidth, {sync: true}),
          this.rootEl.resize(this.containerWidth, {sync: true})
        ], {
          beforeStart: function(){
            this.catalog.down('.catalog-home').show();
            this.container.fire('toolbar:deactivate');
            this.container.fade();
            this.currentPageEl = null;
          }.bind(this),
          afterUpdate: function(){ document.fire('layout:changed'); },
          afterFinish: function(){
            this.catalog.removeClassName('expanded');
            this.startRotate();
            $('container').scrollTo();
          }.bind(this)
        });
      }.bind(this)
    });
  },
  
  startRotate: function(){
    var placeholders = $$('.catalog-home .pages .thumb');
    var availPlaces = placeholders.size();
    var allThumbs = this.allThumbs.size();
    
    if(allThumbs <= availPlaces) return;
  
    this.rotater = new PeriodicalExecuter(function(){
      var thumbIdx = (Math.random() * availPlaces).floor(), imgIdx;
      do {
        imgIdx = ((Math.random() * (allThumbs-1)) + 0.5).floor();
      } while (this.thumbPages.include(imgIdx));
      this.thumbPages[thumbIdx] = imgIdx;
      placeholders[thumbIdx].writeAttribute('rel', this.allThumbs[imgIdx].pageNum).down('img').crossfade(this.allThumbs[imgIdx].thumb, { duration: 2 });
    }.bind(this), 4);
  },
  
  stopRotate: function(){
    if(this.rotater) {
      this.rotater.stop();
      this.rotater = null;
    }
  },
  
  animatePage: function(options){
    var container = this.container.down('.catalog-page');
    options = Object.extend({
      columns: 12,
      duration: 1,
      speed: 0.1,
      onComplete: Prototype.empty
    }, options || {});
    
    var colWidth = (780/options.columns).round();
    
    options.columns.times(function(idx){
      var column = new Element('div', { className: 'fx-col' }).setStyle({
        left: (colWidth * idx) + 'px',
        width: colWidth + 'px'
      });
      container.insert(column);
    });
    
    Effect.multiple(container.select('.fx-col'), Effect.Fade, { 
      duration: options.duration, 
      speed: options.speed,
      queue: {scope: 'animation'},
      afterFinish: function(fx){
        fx.element.remove();
        if(Effect.Queues.get('animation').effects.length == 0 && typeof options.onComplete != 'undefined')
          options.onComplete.call();
      }
    });
  },
  
  /* Information panel related code */
  
  showPanel: function(data, callbacks){
    new Effect.Parallel([
      this.catalog.resize(1040, {sync: true}),
      this.rootEl.resize(1512, {sync: true}),
      this.catalog.down('.catalog-panel').resize(260, {sync: true})
    ], {
      beforeStart: function(){
        this.buildPanel(data);
        this.initScrollPanel(this.catalog.down('ol.style-list'), this.catalog.down('div.handle'), this.catalog.down('div.scrollbar'), this.catalog.down('ol.style-list').getHeight());
      }.bind(this),
      afterUpdate: function(){ document.fire('layout:changed'); },
      afterFinish: function(){
        this.panelVisible = true;
      }.bind(this)
    });
  },
  
  hidePanel: function(callbacks){
    new Effect.Parallel([
      this.catalog.resize(780, {sync: true}),
      this.rootEl.resize(1252, {sync: true}),
      this.catalog.down('.catalog-panel').resize(0, {sync: true})
    ], {
      afterUpdate: function(){ document.fire('layout:changed'); },
      afterFinish: function(){
        this.panelVisible = false;
        (callbacks && callbacks.onComplete) ? callbacks.onComplete.call(this) : Prototype.empty;
      }.bind(this)
    });
  },
  
  crossfadePanelContent: function(data){
    var styleList = this.catalog.down('.details .scroller-container');
    new Effect.Morph(styleList, {
      style: 'opacity: 0',
      transition: Prototype.Browser.IE ? Effect.Transitions.full : Effect.Transitions.cubic,
      duration: .5,
      afterFinish: function(){
        this.buildPanel(data);
        this.initScrollPanel(this.catalog.down('ol.style-list'), this.catalog.down('div.handle'), this.catalog.down('div.scrollbar'), this.catalog.down('ol.style-list').getHeight());
        new Effect.Morph(styleList, {
          style: 'opacity: 1',
          transition: Prototype.Browser.IE ? Effect.Transitions.full : Effect.Transitions.cubic,
          duration: .5
        });
        
      }.bind(this)
    });
  },
  
  updatePanel: function(data){
    if(!Object.isUndefined(data)) {
      if(this.panelVisible)
        this.crossfadePanelContent(data);
      else
        this.showPanel(data);
    } else
      this.hidePanel();
  },
  
  buildPanel: function(data){
    var styleList = this.catalog.down('.details ol.style-list').update();
    var linksList = this.catalog.down('.details ol.links-list').update();
    
    this.data.links.each(function(link){
      linksList.insert({'bottom': this.linkTmp.evaluate(link)});
    }.bind(this));
    
	
    $A(data).each(function(obj){
	  if (typeof obj.price == undefined || obj.price == '')
      	styleList.insert({'bottom': this.styleNoPriceTmp.evaluate(obj)});
	  else {
		if (Gucci.getTerm('price-commas') == 'true')
			obj.price = this.addPriceCommas(obj.price);
		styleList.insert({'bottom': this.styleTmp.evaluate(obj)});
	  }
    }.bind(this));
  },
  
  initScrollPanel: function(panel, handle, track, scrollHeight) {
    /* Mouse wheel for panels */
    var wheelCallback = function(e){
      var delta = Event.wheel(e);
      var factor = Prototype.Browser.WebKit ? 0.03 : 0.07;
      this.scrollPanel.setValueBy(delta > 0 ? -factor : factor);
    };
    
    var wheelEvent = wheelCallback.bindAsEventListener(this);
    // Reset scrollable area state
    panel.setStyle({ top: '0px' });
    panel.stopObserving('mousewheel');
    panel.stopObserving('DOMMouseScroll'); // Firefox
    
    var panelContainerHeight = panel.up().getHeight();
    if(panelContainerHeight < (scrollHeight || 372)) {
      $(track).show();
      this.scrollPanel = new Control.Slider(handle, track, { 
        axis: 'vertical',
        onSlide:function(v) {
          panel.setStyle('top: -' + v*(scrollHeight - panelContainerHeight) + 'px');
        },
        onChange:function(v) {
          panel.setStyle('top: -' + v*(scrollHeight - panelContainerHeight) + 'px');
        }
      });
      panel.observe('mousewheel', wheelEvent);
      panel.observe('DOMMouseScroll', wheelEvent); // Firefox
    } else
      $(track).hide(); //display none for scrollbar if not needed
  }
});

// Event listeners for numerous layout fixes
(function(){
  var events = [
    [window, 'scroll'], 
    [window, 'resize'],
    [document, 'dom:loaded'], 
    [document, 'layout:changed']
  ];
  var container = $('container');
  var header = $('header-content');
  
  // Flicker removing for IE6
  if(Prototype.Browser.IE6)
    try {
      document.execCommand('BackgroundImageCache', false, true);
    } catch(e) {}
  
  events.each(function(event){
    Event.observe(event[0], event[1], function(e){
      if(document.viewport.getHeight() <= container.getHeight()) {
        if(!container.hasClassName('absolute')) {
          container.addClassName('absolute');
        }
      } else {
        if(container.hasClassName('absolute')) {
          container.removeClassName('absolute');
          header.setStyle({
            marginLeft: '-65px',
            width: '100%'
          });
        }   
      }
      
      if(Prototype.Browser.IE6 || container.hasClassName('absolute')) {
        // Emulating position: fixed and max-width for IE6
        var docWidth = document.viewport.getWidth();
        var docScrollLeft = document.viewport.getScrollOffsets()[0];
        var containerWidth = container.getWidth();
        header.setStyle({
          marginLeft: (docScrollLeft) + 'px',
          width: (docWidth - 60) < containerWidth ? (docWidth - 65) + 'px' : '100%'
        });
      } else {
        // Setting max-width for modern browsers
        header.setStyle('max-width: ' + (container.getWidth() + 65) + 'px');
      }
    });
  });
})();