HTMLImageElement.prototype.grayscale = function() {     
  var canvas = document.createElement('canvas');
  
  var canvasContext = canvas.getContext('2d');
  var imgObj = new Image();
  imgObj.src = this.src;
  var imgW = imgObj.width;
  
  var imgH = imgObj.height;
  canvas.width = imgW;
  canvas.height = imgH;
  canvasContext.drawImage(imgObj, 0, 0);
  
  var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);

  for(var y = 0; y < imgPixels.height; y++){
       for(var x = 0; x < imgPixels.width; x++){
            var i = (y * 4) * imgPixels.width + x * 4;
            var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
            imgPixels.data[i] = avg;
            imgPixels.data[i + 1] = avg;
            imgPixels.data[i + 2] = avg;
       }
  }
  
  canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
  
  imgObj.className = 'grayscale';
  imgObj.src = canvas.toDataURL();
  
  return imgObj;
};


function Reference($element){
		var self = this;
		self.clickedClientID = -1;
		self.clickedProjectID = -1;

		self.$reference_element = $('#references');
		
		self.$rows = self.$reference_element.find('.row');
		self.$activeProject = null;
		
		// consts (size + gap)
		self.GAP = 10;
		self.CLIENT_WIDTH = 195 + self.GAP;
		self.CLIENT_HEIGHT = 126 + self.GAP;

		var clientGloablID = 0;

		// set positions
		self.$rows.each(function(rowID, row) 
		{

			$(row).css('top', self.CLIENT_HEIGHT * rowID);
			$(row).data({'top': self.CLIENT_HEIGHT * rowID});
			$(row).find('.client').each(function(clientID, client)
			{
				
				$(client).data({'row': rowID, 'id': clientID, 'slideshow': new Slideshow(clientGloablID++, $(client).find('.projects .project').length, self.closeSlideshow, self.slideshowLoaded)});
				$(client).find('.logo').css('left', self.CLIENT_WIDTH * clientID);
				$(client).find('.projects').css('top', self.CLIENT_HEIGHT - self.GAP);
				$(client).find('.projects .project').each(function(projectID, project)
				{
					$(project).css('left', self.CLIENT_WIDTH * (projectID % 4));
					$(project).css('top', self.GAP + self.CLIENT_HEIGHT * Math.floor(projectID / 4));
					$(client).find('.projects').data({'height': self.CLIENT_HEIGHT + self.CLIENT_HEIGHT * Math.floor(projectID / 4)});
				});
				// align projects to logo center
				var numProjects = $(client).find('.projects .project').length;
				if (numProjects < 4 && clientID > 0)
					$(client).find('.projects').css('left', (self.CLIENT_WIDTH * clientID) - (Math.floor(numProjects / 2) * self.CLIENT_WIDTH));
			});
		});


		// create greyscale images
		self.$reference_element.find('.logo .cover').onImagesLoaded(function(_this) {
			$(_this).fadeIn(200);

			$(_this).parent().prepend(_this.grayscale());
		});

		this.registerHooks();
	};



Reference.prototype.showProjects = function(target) 
	{
		var self = this;
		var $target = $(target).parent();
		var $all_projects = self.$rows.find('.projects');
		var $all_rollovers = self.$rows.find('.rollover');
		var $all_covers = self.$rows.find('.cover');
		var $all_logos = self.$rows.find('.logo');
		var $projects = $target.find('.projects');


		// reset state if clicked on opened project
		if (self.$activeProject && $target.data() == self.$activeProject.data()) {
			
			$all_projects.animate({height: 0},{duration: 1200, easing: 'easeOutExpo', queue:false});
			$all_projects.animate({opacity: 0}, {duration: 800, easing: 'easeOutSine', queue:false});
			$all_rollovers.animate({opacity: 0}, {duration: 500, easing: 'easeOutSine', queue:false});
			$all_covers.animate({opacity: 1}, {duration: 500, easing: 'easeOutSine', queue:false});
			$all_logos.animate({opacity: 1}, {duration: 500, easing: 'easeOutSine', queue:false});

			self.$rows.each(function(rowID, row) { 
				$(row).animate({top: $(row).data('top')}, {duration: 1200, easing: 'easeOutExpo', queue:false});
			});

			self.$activeProject = null;
			return;
		}

		// disable projects height and opacity
		$all_projects.animate({height: 0},{duration: 1200, easing: 'easeOutExpo', queue:false});
		$all_projects.animate({opacity: 0}, {duration: 800, easing: 'easeOutSine', queue:false});
		$all_rollovers.animate({opacity: 0}, {duration: 300, easing: 'easeOutSine', queue:false});
		$all_covers.animate({opacity: 0}, {duration: 300, easing: 'easeOutSine', queue:false});
		$all_logos.animate({opacity: 0.5}, {duration: 300, easing: 'easeOutSine', queue:false});
		$all_projects.css('z-index', 100);
		
		// enable projects height and opacity for current project
		$target.parent().find('.projects').each(function(projectsID, projectsItem){
			if (projectsItem != $projects[0])	$(projectsItem).animate({height: $projects.data('height')},{duration: 1200, easing: 'easeOutExpo', queue:false, complete:function(){$(this).hide(); }});
			else 								$(projectsItem).animate({height: $projects.data('height')},{duration: 1200, easing: 'easeOutExpo', queue:false});
		});
		$projects.animate({opacity: 1}, {duration: 800, easing: 'easeOutSine', queue:false});
		$target.find('.rollover').animate({opacity: 1}, {duration: 300, easing: 'easeOutSine', queue:false});
		$target.find('.cover').animate({opacity: 1}, {duration: 300, easing: 'easeOutSine', queue:false});
		$target.find('.logo').animate({opacity: 1}, {duration: 300, easing: 'easeOutSine', queue:false});
		$projects.css('z-index', 110);

		// set row positions
		self.$rows.each(function(rowID, row) 
		{
			if (rowID < $target.data('row') + 1)	$(row).animate({top: $(row).data('top')}, {duration: 1200, easing: 'easeOutExpo', queue:false});
			else 									$(row).animate({top: $(row).data('top') + $projects.data('height')}, {duration: 1200, easing: 'easeOutExpo', queue:false});
		});

		self.$activeProject = $target;
	};

Reference.prototype.slideshowLoaded = function(slideshow) {
		$('#references').animate({opacity: 0}, {duration: 200, easing: 'linear', queue:false, complete:function(){$(this).hide(); }});
		$('#references .project .loader').hide();
		$('#slideshowContainer').show();
		$('#slideshowContainer').animate({opacity: 1}, {duration: 200, easing: 'linear', queue:false});
		
		$('#slideshowContainer').empty();
		$('#slideshowContainer').append(slideshow.$div);
		slideshow.registerHooks();
	};

Reference.prototype.closeSlideshow = function(slideshow) {
		$('#references').show();
		$('#references').animate({opacity: 1}, {duration: 200, easing: 'linear', queue:false});
		$('#slideshowContainer').animate({opacity: 0}, {duration: 200, easing: 'linear', queue:false, complete:function(){$(this).hide(); }});
	};
	
Reference.prototype.registerHooks = function(element) {
		var self = this;
		
		/* projects navigation */
		this.$reference_element.find('.logo').bind('click', function() { self.showProjects(this); });
		this.$reference_element.find('a').bind('click', function(event) { 
			var ref = $(this).attr('ref').split('|');
			var slideshow = $(this).parent().parent().data('slideshow');
			
			//self.loadProjectCase(this, ref[0], ref[1], "center"); 
			$(this).find('.loader').fadeIn({duration: 100});

			slideshow.loadSlideshow(ref[1], false);

			event.preventDefault();
			event.stopPropagation();
		});

		return this;
	};
