var gallery;

var imagePath = "http://media.nterface.com/images/";

// A container to preload the images
var images = new Array();


/*-------------------------------- Hash Monitor --------------------------------*/

var HashMonitor = Class.create( {
	initialize: function(options) {
		var base = this;
		
		this.lastHashValue = window.location.hash;
		
		// Monitor the forward and back events
		new PeriodicalExecuter(function(pe) {
  			if(window.location.hash == base.lastHashValue) {
				return; // The hash value has not changed since it was last checked
			}
	
			// The hash has changed
			base.lastHashValue = window.location.hash;
		
			var hashValue = window.location.hash.split("#")[1];
			
			if(hashValue && hashValue.length > 0) {				
				options.onChange(hashValue);
			}
		}, 0.3);
	}
});

/*-------------------------------- Gallery --------------------------------*/

var Gallery = Class.create({
	initialize: function(items, thumbSetting) {
		this.items = items;
		this.unit = -1; // Not yet loaded
		this.set = -1; // Not yet loaded
		this.thumbSetting = thumbSetting;
		this.imagesPerSet = 9;
		this.maxWidth = 800;
		
		if(this.thumbSetting == "Vertical") { 
			this.maxWidth = 640;
			this.imagesPerSet = 28;
		}
		
		this.hasThumbs = this.thumbSetting != "Off";
				
		// Defaults
		this.captionEl = $('caption');
		this.loadingEl = $('loading');
		this.photoEl = $('artwork');
		this.photoBoxEl = $('inner');
		this.counterEl = $('counter');
		this.prevLinkEl = $('prevLink');
		this.nextLinkEl = $('nextLink');
		
		// Load the initial image
		var hashValue = window.location.hash.split("#")[1];
				
		if(hashValue && hashValue.length > 0) {
			var hashImage = parseInt(hashValue) -1;
			
			this.view(hashImage);
		}
		else {
			this.view(0);
		}
		
		this.preloadImages(); // Pre-load the rest of the images

		var base = this;
		
		var hashMonitor = new HashMonitor({ 
			onChange: function(hashValue){
				var itemIndex = hashValue - 1;
				
				if(itemIndex != gallery.unit) {
					// alert("Browser nav event detected");
					// Logger.Info("Browser navigation detected", true);
					
					base.view(itemIndex);
				}
			}
		});
	},
	getCurrentSet: function() {	
		return Math.floor((this.unit / this.imagesPerSet) + 1);
	},
	view: function(itemIndex) {			
		var i = parseInt(itemIndex);
		
		if(i == this.unit) {
			return; // don't load again.
		}
		
		// Make sure they are viewing a valid image
		if(this.items.length <= i || i < 0) {	
			//alert('Image out of bounds');
			//Logger.Info("Image out of bounds", true);
			return;	
		}

		this.unit = i;

		// window.location = "#" + (this.unit + 1); // Update the hash
		
		this.animationStart();
	},
	viewNext: function() {
		this.view(this.unit + 1);
	},
	viewPrevious: function() {
		this.view(this.unit - 1);
	},
	animationStart: function() {
		var base = this;
			
		// Show the loading image
		this.loadingEl.show();

		// Hide the caption
		this.captionEl.hide();

		// Hide the previous and back buttons
		[this.prevLinkEl, this.nextLinkEl].each(Element.hide);
		
		//Hide the photo	
		this.photoEl.hide();
		
		// Get the current item
		var item = this.items[this.unit];
		var itemMedia = item.media;

		// Get the dimensions to resize the image box to
		var size = new getDimensions(itemMedia.width, itemMedia.height, this.maxWidth, 660);
		
		var imageUrl = imageUrls[this.unit]; // imagePath + itemMedia.id + "/" + size.width + "x" + size.height + ".jpeg";
		
		// Set anchor for bookmarking
		this.prevLinkEl.href = "#" + (this.unit+1);
		this.nextLinkEl.href = "#" + (this.unit+1);
			
		// Load the photo into a temporary image
		var tempImage = new Image();
		
		tempImage.onload = function() {
			base.photoEl.src = tempImage.src
			base.photoEl.width = size.width; 
			base.photoEl.height = size.height;

			base.animationEnd();
		}

		tempImage.src = imageUrl;		
		
		// Resize the photo box
		this.photoBoxEl.style.height = size.height + "px";
		
		// Set the caption
		if(itemMedia.description.length > 0) {
			this.captionEl.show(); 
		}

		this.captionEl.update(itemMedia.description);
		this.counterEl.update((this.unit + 1) + ' of ' + this.items.length);
		
		// Do the thumbnail stuff
		if(this.hasThumbs) {
			this.loadSet(this.getCurrentSet());
				
			// Remove the current thumbnail class
			$$("li.cur").each(function(li) {
				li.removeClassName('cur');
			});  
	
			thumbnail = $('thumb_' + this.unit);
	
			if(thumbnail) {
				thumbnail.addClassName('cur');
			}
		}
	},
	animationEnd: function(){
		var base = this;
			
		new Effect.Fade(this.loadingEl, {duration: 0.2});

		new Effect.Appear(this.photoEl, {
			duration: 0.3,
			queue: 'end', 
			afterFinish: function() {	
				if(base.items.length > 1) {
					[base.prevLinkEl, base.nextLinkEl].each(Element.show);
				}
			}
		});
	},
	loadSet: function(set) {
		if(!this.hasSet(set) || this.set == set) {
			return;
		}
				
		this.set = set;
		
		this.setEnd = (this.set * this.imagesPerSet) - 1;
		this.setStart = this.setEnd - (this.imagesPerSet - 1);

		if(this.set == 1) {
			$("prev_set").addClassName("dis");
		}
		else {
			$("prev_set").removeClassName("dis");
		}
		
		if(this.hasSet(set + 1)) {
			$("next_set").removeClassName("dis");
		}
		else {
			$("next_set").addClassName("dis");
		}
				
		this.loadThumbs(this.setStart, this.imagesPerSet);
	},
	hasSet: function(set) {
		var totalSets = Math.ceil(this.items.length / this.imagesPerSet);
		
		return set <= totalSets && set > 0;
	},
	previousSet : function() {
	
		this.loadSet(this.set - 1);
	},
	nextSet : function() {
	
		this.loadSet(this.set + 1);
	},
	moveTo: function(element, container, options) {
		this.current = $(element);

		Position.prepare();
	    	
	    var containerOffset = Position.cumulativeOffset(container);
	    var elementOffset = Position.cumulativeOffset(element);
	
		var x = (elementOffset[0]-containerOffset[0]);
		var y = (elementOffset[1]-containerOffset[1]);
		
		if(options.yOffset) {
			y += options.yOffset;
		}
		
		this.scrolling 	= new Effect.SmoothScroll(container, { 
			duration:options.duration, 
			x:x, 
			y:y
		});
		  
		 return false;
	},
	loadThumbs: function(offset, limit) {		
		var wrapper = $('wrapper');
		
		if(wrapper) {

			var elementToMoveTo = $('thumb_' + offset);
		
			this.moveTo(elementToMoveTo, wrapper, {  duration: 0.5 }  );				
		}


		// alert('load:{' + offset + ":" + limit + "}");
		
		this.setStart = offset;
		this.setEnd = offset + (limit - 1);

		if(this.setEnd >= this.items.length) {
			this.setEnd = (this.items.length - 1);
		}

		// Load the thumbs in this batch
		for(var i = this.setStart; this.setEnd >= i; i++) {
		
			var imageArt = $('imageArt_' + i);
				
			if(imageArt.src.indexOf("?") > -1)
			{
				imageArt.src = imageArt.src.split("?")[1];
			}
				
			if(this.thumbSetting == "Vertical") {
				var imageArt2 = $('imageArt2_' + i)
								
				if(imageArt2.src.indexOf("?") > -1)
				{
					imageArt2.src = imageArt2.src.split("?")[1];
				}
			}
		}
		
		if(this.thumbSetting == "Vertical") {
		
			// Hide all the photos
			for(var i = 0; this.items.length > i; i++) {
				$('thumb_' + i).hide();
			}

			// Show the thumbs in this batch
			for(var i = this.setStart; this.setEnd >= i; i++) {
				$('thumb_' + i).show();
			}
		}
	},
	preloadImages: function() {			
		// Preload the images
		for(i = 0; i < this.items.length; i++) {
			var imageUrl = imageUrls[i]; // this.getImageUrl(i, this.maxWidth, 660);
			
			images[i] = new Image();
			
			images[i].src = imageUrl;
		}
	},
	getImageUrl: function(itemIndex, maxWidth, maxHeight) {
		var item = this.items[itemIndex];
		var itemMedia = item.media;
			
		var size = new getDimensions(itemMedia.width, itemMedia.height, maxWidth, maxHeight);
	
		var imageUrl = imagePath + itemMedia.id + "/" + size.width + "x" + size.height + ".jpeg";
		
		return imageUrl;
	}
});

function getDimensions(width, height, maxWidth, maxHeight) {
	if (height <= maxHeight && width <= maxWidth) {

		this.width = width;
		this.height = height;
	}
	else {	
		mutiplier = (maxWidth / width);

    	if (height * mutiplier <= maxHeight) {
			newHeight = Math.round(height * mutiplier);

			this.width = maxWidth;
			this.height = newHeight;
      	}
		else {
        	mutiplier = (maxHeight / height);

            newWidth = Math.round(width * mutiplier);

			this.width = newWidth;
			this.height = maxHeight;
		}
	}
}
	
/*------------------------------------------------*/

var SlideshowRules = {
	'#prevLink:click': function(element) {
		gallery.viewPrevious();
	},
	'#nextLink:click': function(element) {
		gallery.viewNext();
	},
	'a:focus': function(element) {
		element.blur();
	}
};

// Copyright (c) 2005-2006 Justin Palmer (http://encytemedia.com)
// Examples and documentation (http://encytemedia.com/event-selectors)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

var EventSelectors = {
  version: '1.0_pre',
  cache: [],

  addLoadEvent : function(func) {
     var oldonload = window.onload;
		
     if (typeof window.onload != 'function') {
	  window.onload = func;
     } 
     else {
         window.onload = function() {
	      oldonload();
		func();
		}
     }
  },

  start: function(rules) {
    this.rules = rules || {};
    this.timer = new Array();
    this._extendRules();
    this.assign(this.rules);
  },
  
  assign: function(rules) {
    var observer = null;
    this._unloadCache();
    rules._each(function(rule) {
      var selectors = $A(rule.key.split(','));
      selectors.each(function(selector) {        
        var pair = selector.split(':');
        var event = pair[1];
        $$(pair[0]).each(function(element) {
          if(pair[1] == '' || pair.length == 1) return rule.value(element);
          if(event.toLowerCase() == 'loaded') {
            this.timer[pair[0]] = setInterval(this._checkLoaded.bind(this, element, pair[0], rule), 15);
          } else {
            observer = function(event) {
              var element = Event.element(event);
              if (element.nodeType == 3) // Safari Bug (Fixed in Webkit)
            		element = element.parentNode;
              rule.value($(element), event);
            }
            this.cache.push([element, event, observer]);
            Event.observe(element, event, observer);
          }
        }.bind(this));
      }.bind(this));
    }.bind(this));
  },
  
  // Scoped caches would rock.
  _unloadCache: function() {
    if (!this.cache) return;
    for (var i = 0; i < this.cache.length; i++) {
      Event.stopObserving.apply(this, this.cache[i]);
      this.cache[i][0] = null;
    }
    this.cache = [];
  },
  
  _checkLoaded: function(element, timer, rule) {
    var node = $(element);
    if(element.tagName != 'undefined') {
      clearInterval(this.timer[timer]);
      rule.value(node);
    }
  },
  
  _extendRules: function() {
    Object.extend(this.rules, {
     _each: function(iterator) {
       for (key in this) {
         if(key == '_each') continue;         
         var value = this[key];
         var pair = [key, value];
         pair.key = key;
         pair.value = value;
         iterator(pair);
       }
     }  
    });
  }
}

// Project Rules 
var ProjectRules = {
	'#details:click' : function(element) {
		$('details').hide();
		
		//new Effect.Fade('details', {duration: 0.3});

		if($('projTitleMo')) {
			$('projTitleMo').show();
		}
	},
	'#details:mouseover' : function(element) {
		$('details').addClassName('projNotesHov');
	},
	'#details:mouseout' : function(element) {
		$('details').removeClassName('projNotesHov');
	},
	'#projTitle:click' : function(element) {
		//new Effect.Appear('details', {duration: 0.4});
		
		$('details').show();
		
		$('projNotePlus').hide();
		$('projNoteTxt').hide();
	},
	'#projTitle:mouseover' : function(element) {
		$('projTitle').addClassName('projNotesHov');
		$('projNotePlus').show();
		$('projNoteTxt').hide();
	},
	'#projTitle:mouseout' : function(element) {
		$('projTitle').removeClassName('projNotesHov');
		$('projNotePlus').hide();
		$('projNoteTxt').hide();
	},
	'#projTitleMo:click' : function(element) {
		$('details').show();
		$('projNotePlus').hide();
		$('projNoteTxt').hide();
		$('projTitleMo').hide();
	},
	'#projTitleMo:mouseover' : function(element) {
		$('projTitleMo').addClassName('projNotesHov');
		$('projNotePlus').show();
		$('projNoteTxt').show();
	},
	'#projTitleMo:mouseout' : function(element) {
		$('projTitleMo').removeClassName('projNotesHov');
		$('projNotePlus').hide();
		$('projNoteTxt').hide();
	}
};




Effect.SmoothScroll = Class.create();
Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'absolute'
    } , arguments[1] || {}  );
    this.start(options);
  },
  setup: function() {
    if (this.options.continuous && !this.element._ext ) {
      this.element.cleanWhitespace();
      this.element._ext=true;
      this.element.appendChild(this.element.firstChild);
    }
   
    this.originalLeft=this.element.scrollLeft;
    this.originalTop=this.element.scrollTop;
   
    if(this.options.mode == 'absolute') {
      this.options.x -= this.originalLeft;
      this.options.y -= this.originalTop;
    } 
  },
  update: function(position) {   
    this.element.scrollLeft = this.options.x * position + this.originalLeft;
    this.element.scrollTop  = this.options.y * position + this.originalTop;
  }
});