/**
 * @depends prototype.js
 * @depends effects.js
 */

/* Prototype Extensions */
Element.addMethods({
  scrollTo: function(element, options){
    var options = arguments[1] || { },
    scrollOffsets = document.viewport.getScrollOffsets(),
    elementOffsets = $(element).cumulativeOffset();

    if (options.offset) elementOffsets[0] += options.offset;

    return new Effect.Tween(null,
      scrollOffsets.left,
      elementOffsets[0],
      options,
      function(p){ scrollTo(p.round(), scrollOffsets.top); }
    );
  },
  
  resize: function(element, width, options){
    var options = Object.extend({
      style: { 'width': width + 'px' }
    }, options || {});
    return new Effect.Morph(element, options);
  },
  
  crossfade: function(element, url, options){
    element = $(element);
    Loader.load(url,{
      onComplete: function(){
        var replacement = new Element('img',{src:url}).setStyle({position:'absolute'});
        element.up().insert({top:replacement});
        element.morph('opacity:0',Object.extend(
          {afterFinish:function(){ element.remove() }},
          options || {}
        ));
      }
    });
  },
  
  delegate: function(element, eventName, delegates){
		return Event.observe(element, eventName, Event.delegate(delegates));
	}
});

/* Effects Cubic transition */
Object.extend(Effect.Transitions, {
  cubic: function(pos) {
    pos /= 0.5; return pos<1 ? 0.5*pos*pos*pos : 0.5*((pos-2)*(pos-2)*(pos-2)+2);
  }
});
Effect.DefaultOptions.transition = Effect.Transitions.cubic;

/* Wheel extension */
Object.extend(Event, {
	wheel:function (event){
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120; 
			if (window.opera) delta = -delta;
		} else if (event.detail) { delta = -event.detail/3;	}
		return Math.round(delta); //Safari Round
	},
	
	localPointer: function(event){
	  var p = [Event.pointerX(event), Event.pointerY(event)];
    var element = arguments[1] || Event.element(event);
    var e = Position.page($(element));
    return [
      p[0]-(e[0]+(window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0)),
      p[1]-(e[1]+(window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop  || 0))
    ];
	},
	
	delegate: function(delegates){
  	return function(e){
  		var element = Event.element(e), elements = [element].concat(element.ancestors());
  		for(var selector in delegates){
  			if (element = Selector.matchElements(elements, selector)[0]){
  				delegates[selector].call(element, e);
  			}
  		}
  	}
  }
});

Object.extend(Prototype.Browser, {
  IE6: !!(window.attachEvent && !window.opera && (/MSIE 6\./.test(navigator.userAgent)))
})

/* Engine Detection. Replace in order to use Prototype.Browser */
var Engine = {
  detect: function() {
    var UA = navigator.userAgent;
    this.isKHTML = /Konqueror|Safari|KHTML/.test(UA);
    this.isGecko = (/Gecko/.test(UA) && !this.isKHTML);
    this.isOpera = /Opera/.test(UA);
    this.isMSIE  = (/MSIE/.test(UA) && !this.isOpera);
	this.isMSIE8 = this.isMSIE && (/MSIE 8\./.test(UA) && !this.isOpera);
    this.isMSIE7 = this.isMSIE && !this.isMSIE8 && !(/MSIE 6\./.test(UA) && !this.isOpera);
    this.isMSIE6 = this.isMSIE && !this.isMSIE7 && !this.isMSIE8;
    if (document.childNodes && !document.all && !navigator.taintEnabled)
      Engine[Prototype.BrowserFeatures.XPath ? 'isSafari3' : 'isSafari2'] = true;
  }
}
Engine.detect();

Position.getPageSize = function() {
  var xScroll, yScroll;

  if (window.scrollMaxX) {  
    xScroll = window.innerWidth  + window.scrollMaxX;
    yScroll = window.innerHeight + window.scrollMaxY;
  } else {
    xScroll = document.body.scrollWidth;
    yScroll = document.body.scrollHeight;
  } 
  
  var windowWidth, windowHeight;
  if (self.innerHeight) { // all except Explorer
    windowWidth = self.innerWidth;
    windowHeight = self.innerHeight;
  } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
    windowWidth = document.documentElement.clientWidth;
    windowHeight = document.documentElement.clientHeight;
  } else if (document.body) { // other Explorers
    windowWidth = document.body.clientWidth;
    windowHeight = document.body.clientHeight;
  }
  // for small pages with total height less then height of the viewport
  pageHeight = Math.max(windowHeight, yScroll);

  // for small pages with total width less then width of the viewport
  pageWidth = Math.max(windowWidth, xScroll);

  return { page: { width: pageWidth, height: pageHeight }, window: { width: windowWidth, height: windowHeight } };
}

/* Gucci Extensions */
if (!Gucci) var Gucci = {};

function $t(term){
  document.write(Gucci.getTerm(term));
}

Object.extend(Gucci, {
  setMenu: function(items){
    Menu.items = items;
  },
  
  openPopup: function(url) {
	var w = window.open(url,'gucci','height=450,width=395,directories=no,location=no,menubar=no,scrollbars=yes,status=no,toolbar=no,resizable=no');
    w.focus();
  },
  
  getPageFragmentIdentifier: function(){
    return location.href.split('#').inGroupsOf(2).flatten()[1];
  },
  
  setPageFragmentIdentifier: function(id){
    var url = location.href.split('#');
    location.href = url[0] + '#' + id;
  },
  
  getTerm: function(term){
    return Menu.items ? (Menu.items.term[term] || '!('+term+')') : '!(menu missing?)';
  }
});

Effect.HScrollTo = Class.create();
Object.extend(Object.extend(Effect.HScrollTo.prototype, Effect.Base.prototype), {
  initialize: function(scrollEnd) {
    this.container  = $('snippets_container');
    this.scrollStart = this.container.scrollLeft; //window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
    
    var delta = scrollEnd - this.scrollStart;
    var w = Position.getPageSize();
    var width = this.container.scrollWidth;
    
    if(this.scrollStart + delta < 0) delta = -this.scrollStart;
    if(this.scrollStart + delta > (width-w.window.width)) 
      delta = (width-w.window.width) - this.scrollStart;
    
    this.delta   = delta;
    
    this.start(arguments[1] || {});
  },
  update: function(position) {
    this.container.scrollLeft = (this.scrollStart + (position*this.delta)).round(); 
  }
});

Effect.MoveRight = Class.create();
Object.extend(Object.extend(Effect.MoveRight.prototype, Effect.Base.prototype), {
  initialize: function(element, delta) {
    this.element = $(element);
    if(!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    delta
    }, arguments[2] || {});
    this.start(options);
  },
  setup: function() {
    this.originalRight = this.options.initialRight || parseFloat(this.element.getStyle('right') || '0');
  },
  update: function(position) {
    this.element.setStyle({
      right: Math.round(this.options.x  * position + this.originalRight) + 'px'
    });
  }
});

Effect.ZoomIn360 = Class.create();
Object.extend(Object.extend(Effect.ZoomIn360.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    var options = Object.extend({}, arguments[1] || {});
    
    var m = [options.pointer[0], options.pointer[1]];
    if(m[1]<99) m[1] = 99;
    if(m[1]>382) m[1] = 382;
    m[0] = m[0]*(Gucci.Zoomer.FACTOR)*(Gucci.Zoomer.expand ? 0.5 : 0.75);   
    m[1] = m[1]*(Gucci.Zoomer.FACTOR)*0.75;
    this.translate = [ -m[0], -m[1] ];
    this.scale     = [ ((1032*options.frames)-(260*options.frames)), (2000-504) ];
    this.start(options);
  },
  update: function(position) {
    var style = {
        left: Math.round(this.element.deltax + ((this.element.deltax*Gucci.Zoomer.FACTOR - this.element.deltax) * position)) +
              Math.round(this.translate[0] * position) + 'px',
         top: Math.round(this.translate[1] * position) + 'px',
       width: (260*this.options.frames) + Math.round(this.scale[0] * position) + 'px',
      height: 504  + Math.round(this.scale[1] * position) + 'px'
    };
    this.element.setStyle(style);
  }
});


Effect.ZoomOut360 = Class.create();
Object.extend(Object.extend(Effect.ZoomOut360.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    var options = Object.extend({}, arguments[1] || {});
    this.start(options);
  },
  setup: function(){
    this.origin = [
      Math.round(this.element.offsetLeft - this.element.deltax*Gucci.Zoomer.FACTOR),
      this.element.offsetTop
    ];
    this.translate = [ -this.origin[0], -this.origin[1] ];
    this.scale = [ ((1032*this.options.frames)-(260*this.options.frames)), (2000-504) ];    
  },
  update: function(position){
    var style = {
        left: Math.round(this.element.deltax + ((this.element.deltax*Gucci.Zoomer.FACTOR - this.element.deltax) * (1-position))) +
              this.origin[0] + Math.round(this.translate[0] * position) + 'px',
         top: this.origin[1] + Math.round(this.translate[1] * position) + 'px',
       width: 1032*this.options.frames - Math.round(this.scale[0] * position) + 'px',
      height: 2000  - Math.round(this.scale[1] * position) + 'px'
    };    
    this.element.setStyle(style);
  }
});

function scrollToHeadline(headline){
  var find = headline.innerHTML.gsub(/\s/,'');
  var e = $$('h1').detect(function(h){  return (h.innerHTML.gsub(/\s/,'') == find) });
  if(!e) return;
  var p = Position.page(e);
  new Effect.HScrollTo(p[0]-15-32,{transition:Gucci.cubic});
}

Gucci._scrollPanels = {};
Gucci.scrollPanel = function(panel, handle, track, scrollHeight) {
  if(panel.scrollHeight > (scrollHeight || 372)) {
    panel.addClassName('with-scrollbar');
    $(track).style.display = 'block';
    this._scrollPanels[panel] = new Control.Slider( handle, track, { 
      axis: 'vertical',
      onSlide:function(v) { 
        var height = panel.scrollHeight;
        panel.scrollTop = (v*(height-(scrollHeight || 372)));
      },
      onChange:function(v) {
        var height = panel.scrollHeight;
        panel.scrollTop = (v*(height-(scrollHeight || 372)));
      }
    });
    wheelCallback = function(delta){
      var factor = Engine.isKHTML ? 0.03 : 0.07;
      Gucci._scrollPanels[panel].setValueBy(delta > 0 ? -factor : factor);
    }
  }
};