﻿/**
  * File:           ImageReflection.js
  * Author:         Mbonisi Masilela
  * Date:           02/18/09
  *
  * Description:    Contains functions that enables images in Notes to have a cool reflection.
  *                 Any image that you want reflected must have the class defined by the 
  *                 IMAGEREFLECTION_CLASSNAME below.
  *
  *                 Example Usage:
  *                     <img src="images/mypic.jpg" class="reflect opacity:40 height:75" alt="My Pic"/>
  *
  *                     reflect - The reflection class
  *                     opacity - As a percent without the % sign. 
  *                               0   opacity means the reflection will be invisible
  *                               100 opacity means the reflection will be solid
  *                               Usually 30 - 50 opacity looks good
  *                     height  - As a percentage of the image's original height,
  *                                 e.g. if the image was 200px, with height:75 
  *                                      the reflection will be 150px (75% of 200px)
  */

var IMAGEREFLECTION_DEFAULT_HEIGHT             = .5;
var IMAGEREFLECTION_DEFAULT_OPACITY            = .5;
var IMAGEREFLECTION_CLASSNAME                  = "reflect";
var IMAGEREFLECTION_CLASSNAME_AFTER_REFLECTION = "reflected_image";

function ImageReflection_GetReflectionImages(imageReflectionClassName)
{
	var allImages = document.getElementsByTagName('img');
	var reflectionImages = new Array();
  
	for(i = 0; i < allImages.length; i++) 
	{
		var imageClassNames = allImages[i].className.split(' ');
		for (j = 0; j < imageClassNames.length; j++) 
		{
			if (imageClassNames[j] == imageReflectionClassName || imageClassNames[j] == IMAGEREFLECTION_CLASSNAME_AFTER_REFLECTION) 
			{
				reflectionImages.push(allImages[i]);
				break;
			}
		}
	}
	return reflectionImages;
}

function ImageReflection_RemoveReflection(reflectedImage)
{
	if(reflectedImage.className == IMAGEREFLECTION_CLASSNAME_AFTER_REFLECTION) 
	{
		reflectedImage.className = reflectedImage.parentNode.className + " reflect";
		reflectedImage.parentNode.parentNode.replaceChild(reflectedImage, reflectedImage.parentNode);
	}
}

function ImageReflection_AddReflection(image, height, opacity)
{
    var originalImage = image;
	
	ImageReflection_RemoveReflection(originalImage);

	try 
	{
		var reflectionWidth     = originalImage.width;
		var reflectionHeight    = Math.floor(originalImage.height * height);
		var reflectionDIVHeight = Math.floor(originalImage.height * (1 + height));
			
	    var originalImageClasses = originalImage.className.split(' ');
		var reflectionDIV        = document.createElement('div');				
		var newImageClasses      = '';
		
		for (j = 0; j < originalImageClasses.length; j++) 
		{
			if (originalImageClasses[j] != IMAGEREFLECTION_CLASSNAME) 
			{
				newImageClasses += originalImageClasses[j] + ' ';
			}
		}

		originalImage.style.cssText = 'vertical-align: bottom';
		originalImage.className     = IMAGEREFLECTION_CLASSNAME_AFTER_REFLECTION;
		
		reflectionDIV.className     = newImageClasses;
		reflectionDIV.style.cssText = originalImage.style.cssText;
		
					
		if(Browser_IE()) 
		{		
		    //For Internet Explorer
			var reflectionImage           = document.createElement('img');
						
			reflectionImage.src           = originalImage.src;
			reflectionImage.style.height  = originalImage.height + 'px';
			reflectionImage.style.width   = reflectionWidth + 'px';			
			reflectionImage.style.marginBottom = "-" + (originalImage.height - reflectionHeight) + 'px';
			reflectionImage.style.filter  = 
			    'flipv progid:DXImageTransform.Microsoft.Alpha(opacity=' + 
			    (opacity * 100) + 
			    ', style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=' + 
			    (height * 100) + 
			    ')';			
			
			reflectionDIV.style.height = reflectionDIVHeight + 'px';
			reflectionDIV.style.width  = reflectionWidth + 'px';
			
			originalImage.parentNode.replaceChild(reflectionDIV, originalImage);
			reflectionDIV.appendChild(originalImage);
			reflectionDIV.appendChild(reflectionImage);			
		} 
		else 
		{
		    //For non Internet Explorer Browsers
			var canvas = document.createElement('canvas');
			if (canvas.getContext) 
			{
				var context = canvas.getContext("2d");
			
				canvas.style.height = reflectionHeight + 'px';
				canvas.style.width = reflectionWidth + 'px';
				canvas.height = reflectionHeight;
				canvas.width = reflectionWidth;
				
				reflectionDIV.style.width = reflectionWidth + 'px';
				reflectionDIV.style.height = reflectionDIVHeight + 'px';
				originalImage.parentNode.replaceChild(reflectionDIV, originalImage);
				
				reflectionDIV.appendChild(originalImage);
				reflectionDIV.appendChild(canvas);
				
				context.save();
				
				context.translate(0, originalImage.height - 1);
				context.scale(1, -1);
				
				context.drawImage(originalImage, 0, 0, reflectionWidth, originalImage.height);

				context.restore();
				
				context.globalCompositeOperation = "destination-out";
				var gradient = context.createLinearGradient(0, 0, 0, reflectionHeight);
				
				gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
				gradient.addColorStop(0, "rgba(255, 255, 255, " + (1 - opacity) + ")");
	
				context.fillStyle = gradient;
				context.rect(0, 0, reflectionWidth, reflectionHeight * 2);
				context.fill();
			}
		}
	} 
	catch (e) 
	{
    }
}

function ImageReflection_AddImageReflections() 
{
	var reflectionImages = ImageReflection_GetReflectionImages(IMAGEREFLECTION_CLASSNAME);
	
	for (i = 0; i < reflectionImages.length; i++) 
	{
		var height  = IMAGEREFLECTION_DEFAULT_HEIGHT;
		var opacity = IMAGEREFLECTION_DEFAULT_OPACITY;	
		
		/* At most there should be 2 options, i.e. opacity and height*/	
		var reflectionOptions = reflectionImages[i].className.split(' ');
		
		for (j = 0; j < reflectionOptions.length; j++) 
		{
		    /* We must also substring away the : from the option e.g. in height:80*/
			if (reflectionOptions[j].indexOf("opacity") == 0) 
			{
			    try
			    {
				    opacity = reflectionOptions[j].substring(8) / 100;
				}
				catch(e){}
			}
					
			if (reflectionOptions[j].indexOf("height") == 0)
			{
			    try
			    {
				    height = reflectionOptions[j].substring(7) / 100;
				}
				catch(e){}				
			} 
		}
		
		ImageReflection_AddReflection(reflectionImages[i], height, opacity);
	}
}
