<!--//

/**
 * JSBach 
 *
 *
 *
 * @author:		Carlo Dal Pont <dalpont.carlo@gmail.com>
 * @license:		http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
 * @package:		JSBach
 * @version:		8.9.21
 * @release:		stable
 */



/**
 * Every animated element should be declared as a new object:
 * var myvar = new JSBach(arg);
 */

function JSBach (id_or_element) {

	/**
	* Preparing timer variables
	*/
	var doFade_timer;
	var doMove_timer;
	var doMoveBackground_timer
	var doResize_timer;
	var doTextResize_timer;
	var doZoom_timer;
	var doEllipse_timer;
	var doColorChange_bg_timer;
	var doColorChange_txt_timer;
	var doColorCycle_bg_timer;
	var doColorCycle_txt_timer;

	var browser;
	var element;

	/**
	* Check if the argument is an id or an element, then assign
	* to the variable element.
	*/
	if (document.getElementById(id_or_element) == null) {
		element = id_or_element;
	}
	else {
		element = document.getElementById(id_or_element)
	}

	/**
	* Different properties for different browsers: sniffs
	* browser.
	*/
	if (navigator.userAgent.search('MSIE') >= 0) {
		browser = 'ie';
	}
	else {
		browser = 'nonie';
	}



	/**
	 * Method for fade effect.
	 */
	this.doFade = function(initial_opacity,final_opacity,duration/*[auto_visibility,fps]*/) {

		var auto_visibility = 0;
		var fps = 34;

		// Clear previous fade effects on the same element
		clearInterval(doFade_timer);

		// Auto visibility optional arguments. Default si 0
		if (arguments[3] != null) {
			auto_visibility = arguments[3];
		}
		// Fps optional argument. Default is 34
		if (arguments[4] != null) {
			fps = arguments[4];
		}

		// Interval is the time between two frames
		var interval = 1000 / fps;
		// Deltaframe is the property value increment between two frames
		var deltaframe = (final_opacity - initial_opacity) * interval / duration;

		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		if (auto_visibility == 1) {
			element.style.visibility = 'visible';
		}

		// This method draw every frame of the animation
		this.frameset = function() {
			if (actual_frame < frames_number) {
				switch (browser) {
				case 'nonie': element.style.opacity = Math.round(initial_opacity) / 100;
				break;
				case 'ie': element.style.filter = 'alpha(opacity='+Math.round(initial_opacity)+')';
				break;
				}
				initial_opacity += deltaframe;
				actual_frame++;
			}
			else {
				switch (browser) {
				case 'nonie': element.style.opacity = final_opacity / 100;
				break;
				case 'ie': element.style.filter = 'alpha(opacity='+final_opacity+')';
				break;
				}
				clearInterval (doFade_timer);
				if ((auto_visibility == 1) && (final_opacity == 0)) {
					element.style.visibility = 'hidden';
				}
			}
			return (initial_opacity);
		}

		// Repeat the frameset method for every frame
		doFade_timer = setInterval(this.frameset , interval);
	}



	/**
	 * Method for move effect.
	 */
	this.doMove = function(initial_x,final_x,initial_y,final_y,duration/*[fps]*/) {
		var fps = 34;

		if (arguments[5] != null) {
			fps = arguments[5];
		}

		clearInterval(doMove_timer);

		var deltaframe_x;
		var deltaframe_y;
		var interval = 1000 / fps;
		if (initial_x != null) {
			var deltaframe_x = (final_x - initial_x) * interval / duration;
		}
		if (initial_y != null) {
			var deltaframe_y = (final_y - initial_y) * interval / duration;
		}
		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		this.frameset = function() {
			if (actual_frame < frames_number) {
				if (initial_x != null) {
					element.style.left = Math.round (initial_x)+'px';
					initial_x += deltaframe_x;
				}
				if (initial_y != null) {
					element.style.top = Math.round (initial_y)+'px';
					initial_y += deltaframe_y;
				}
				actual_frame++;
			}
			else {
				if (final_x != null) {
					element.style.left = Math.round (final_x)+'px';
				}
				if (final_y != null) {
					element.style.top = Math.round (final_y)+'px';
				}
				clearInterval (doMove_timer);
			}
			var position = new Array(initial_x,initial_y);
			return (position);
		}

		doMove_timer = setInterval(this.frameset , interval);
	}



	/**
	 * Method for moving background effect.
	 */
	this.doMoveBackground = function(initial_x,final_x,initial_y,final_y,duration/*[fps]*/) {
		var fps = 34;

		if (arguments[5] != null) {
			fps = arguments[5];
		}

		clearInterval(doMoveBackground_timer);

		var deltaframe_x;
		var deltaframe_y;
		var interval = 1000 / fps;
		if (initial_x != null) {
			var deltaframe_x = (final_x - initial_x) * interval / duration;
		}
		if (initial_y != null) {
			var deltaframe_y = (final_y - initial_y) * interval / duration;
		}
		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		this.frameset = function() {
			if (actual_frame < frames_number) {
				element.style.backgroundPosition = Math.round (initial_x)+'px '+Math.round (initial_y)+'px';
				initial_x += deltaframe_x;
				initial_y += deltaframe_y;
				actual_frame++;
			}
			else {
				element.style.backgroundPosition = Math.round (final_x)+'px '+Math.round (final_y)+'px';
				clearInterval (doMoveBackground_timer);
			}
			var position = new Array(initial_x,initial_y);
			return (position);
		}

		doMoveBackground_timer = setInterval(this.frameset , interval);
	}



	/**
	 * Method for resize effect.
	 */
	this.doResize = function(initial_width,final_width,initial_height,final_height,duration/*[auto_visibility,fps]*/) {
		var auto_visibility = 0;
		var fps = 34;

		clearInterval(doResize_timer);

		if (arguments[5] != null) {
			auto_visibility = arguments[5];
		}
		if (arguments[6] != null) {
			fps = arguments[6];
		}

		var interval = 1000 / fps;
		var deltaframe_width = (final_width - initial_width) * interval / duration;
		var deltaframe_height = (final_height - initial_height) * interval / duration;
		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		if (auto_visibility == 1) {
			element.style.visibility = 'visible';
		}

		this.frameset = function() {
			if (actual_frame < frames_number) {
				if (initial_width >= 0) {
					element.style.width = Math.round(initial_width)+'px';
				}
				if (initial_height >= 0) {
					element.style.height = Math.round(initial_height)+'px';
				}
				initial_width += deltaframe_width;
				initial_height += deltaframe_height;
				actual_frame++;
			}
			else {
				if (initial_width >= 0) {
					element.style.width = final_width+'px';
				}
				if (initial_height >= 0) {
					element.style.height = final_height+'px';
				}
				clearInterval (doResize_timer);
				if ((auto_visibility == 1) && ((final_width == 0) || (final_height == 0))) {
					element.style.visibility = 'hidden';
				}
			}
			var position = new Array(initial_width,initial_height);
			return (position);
		}

		doResize_timer = setInterval(this.frameset , interval);
	}



	/**
	 * Text resize effect
	 */
	this.doTextResize = function(initial_size,final_size,duration/*[fps]*/) {
		clearInterval(doTextResize_timer);

		var fps = 34;
		if (arguments[3] != null) {
			fps = arguments[3];
		}
		var interval = 1000 / fps;
		var deltaframe = (final_size - initial_size) * interval / duration;
		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		this.frameset = function() {
			if (actual_frame < frames_number) {
				element.style.fontSize = initial_size+'px';
				initial_size += deltaframe;
				actual_frame++;
			}
			else {
				element.style.fontSize = final_size+'px';
				clearInterval (doTextResize_timer);
			};
			return (initial_size);
		};

		doTextResize_timer = setInterval(this.frameset , interval);
	};

	/**
	 * Method for zooming effect.
	 */
	this.doZoom = function(initial_width,initial_height,initial_x,initial_y,percentage,duration/*[fps]*/) {

		clearInterval(doZoom_timer);

		var fps = 34;

		if (arguments[6] != null) {
			fps = arguments[6];
		}

		var final_width = (initial_width * percentage) / 100;
		var final_height = (initial_height * percentage) / 100;

		var final_x = initial_x - ((final_width - initial_width) / 2);
		var final_y = initial_y - ((final_height - initial_height) / 2);

		var deltaframe_x;
		var deltaframe_y;
		var interval = 1000 / fps;
		var deltaframe_x = (final_x - initial_x) * interval / duration;
		var deltaframe_y = (final_y - initial_y) * interval / duration;
		var deltaframe_width = (final_width - initial_width) * interval / duration;
		var deltaframe_height = (final_height - initial_height) * interval / duration;

		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		this.frameset = function() {
			if (actual_frame < frames_number) {
				element.style.left = Math.round (initial_x)+'px';
				element.style.top = Math.round (initial_y)+'px';
				element.style.width = Math.round(initial_width)+'px';
				element.style.height = Math.round(initial_height)+'px';
				initial_x += deltaframe_x;
				initial_y += deltaframe_y;
				initial_width += deltaframe_width;
				initial_height += deltaframe_height;
				actual_frame++;
			}
			else {
				element.style.left = Math.round (final_x)+'px';
				element.style.top = Math.round (final_y)+'px';
				element.style.width = Math.round(final_width)+'px';
				element.style.height = Math.round(final_height)+'px';
				clearInterval(doZoom_timer);
			}
			var position = new Array(initial_x,initial_y);
			return (position);
		}

		doZoom_timer = setInterval(this.frameset , interval);
	}



	/**
	 * Method for elliptical motion effect.
	 */
	this.doEllipse = function(center_x,center_y,round_duration,radius_x,radius_y,rotation_direction/*[start_angle,rotation_angle,fps]*/) {
		var start_angle = 0;
		var rotation_angle = 0;
		var fps = 34;

		clearInterval(doEllipse_timer);

		// Optional arguments
		if (arguments[6] != null) {
			start_angle = arguments[6];
		}
		if (arguments[7] != null) {
			rotation_angle = arguments[7];
		}
		if (arguments[8] != null) {
			fps = arguments[8];
		}

		// Convert angles from degrees to radiants
		var start_theta = 2 * Math.PI * ((start_angle - 90) / 360);
		var rotation_rads = 2 * Math.PI * (rotation_angle / 360);
		var theta = start_theta;
		var infinite_rounds = 0;
		if (rotation_rads == 0) {
			infinite_rounds = 1;
		}
		var frame_number = (round_duration / 1000) * fps;
		var delta_theta = 2 * Math.PI * ((360 / frame_number) / 360);
		var interval = Math.round(round_duration / frame_number);

		this.frameset = function() {
			if (infinite_rounds == 1) {
				rotation_rads += delta_theta;
			}
			if (theta < (rotation_rads + start_theta)) {
				switch (rotation_direction) {
				case 1:
					element.style.left = (center_x + Math.round (radius_x * Math.cos (theta)))+'px';
				break;
				case -1:
					element.style.left = (center_x - Math.round (radius_x * Math.cos (theta)))+'px';
				break;
				}
				element.style.top = (center_y + Math.round (radius_y * Math.sin (theta)))+'px';
				theta += delta_theta;
			}
			else {
				element.style.left = (center_x + Math.round (radius_x * Math.cos (rotation_rads + start_theta)))+'px';
				element.style.top = (center_y + Math.round (radius_y * Math.sin (rotation_rads + start_theta)))+'px';
				clearInterval (doEllipse_timer);
			}
			return (theta);
		}

		doEllipse_timer = setInterval(this.frameset , interval);
	}



	/** 
	 * Converting functions needed for color effects
	 */
	function dec2Hex(n) {
		int_n = Math.round(n);
		hex = int_n.toString(16);
		if (hex.length == 1) hex="0"+hex;
		return hex.toUpperCase();
	}
	
	function hex2Dec(s){
		return parseInt(s,16);
	}



	/**
	 * Method for change color.
	 */
	this.doColorChange = function(initial_rgb,final_rgb,duration/*[txt_bg,fps]*/) {

		var txt_bg = 'bg';
		var fps = 34;

		if (arguments[3] != null) {
			txt_bg = arguments[3];
		}
		if (arguments[4] != null) {
			fps = arguments[4];
		}
		
		switch (txt_bg) {
		case 'bg':
			clearInterval (doColorChange_bg_timer);
		break;
		case 'txt':
			clearInterval (doColorChange_txt_timer);
		break;
		}

		// looks for "#" and delete it
		if (initial_rgb.search('#') == 0) {
			initial_rgb = initial_rgb.substr(1,6)
		}
		if (final_rgb.search('#') == 0) {
			final_rgb = final_rgb.substr(1,6)
		}

		var initial_color = new Array;
		var final_color = new Array;
		var deltaframe = new Array;
		var new_rgb;

		//split the rgb string in three colors and convert them to decimal
		initial_color[0] = hex2Dec(initial_rgb.substr(0,2));
		initial_color[1] = hex2Dec(initial_rgb.substr(2,2));
		initial_color[2] = hex2Dec(initial_rgb.substr(4,2));
		final_color[0] = hex2Dec(final_rgb.substr(0,2));
		final_color[1] = hex2Dec(final_rgb.substr(2,2));
		final_color[2] = hex2Dec(final_rgb.substr(4,2));

		var interval = 1000 / fps;
		for (i = 0 ; i < 3 ; i++) {
			deltaframe[i] = (final_color[i] - initial_color[i]) * interval / duration;
		}

		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		this.frameset = function() {
			if (actual_frame < frames_number) {
				new_rgb = '#'+dec2Hex(initial_color[0])+dec2Hex(initial_color[1])+dec2Hex(initial_color[2]);
				switch (txt_bg) {
					case 'bg':
						element.style.backgroundColor = new_rgb;
					break;
					case 'txt':
						element.style.color = new_rgb;
					break;
				}
				for (i = 0 ; i < 3 ; i++) {
					initial_color[i] += deltaframe[i];
				}
				actual_frame++;
			}
			else {
				new_rgb = '#'+dec2Hex(final_color[0])+dec2Hex(final_color[1])+dec2Hex(final_color[2]);
				switch (txt_bg) {
				case 'bg':
					element.style.backgroundColor = new_rgb;
					clearInterval(doColorChange_bg_timer);
				break;
				case 'txt':
					element.style.color = new_rgb;
					clearInterval(doColorChange_txt_timer);
				break;
				}
			}
			return ('#'+dec2Hex(initial_color[0])+dec2Hex(initial_color[1])+dec2Hex(initial_color[2]));
		};

		switch (txt_bg) {
		case 'bg':
			doColorChange_bg_timer = setInterval(this.frameset , interval);
		break;
		case 'txt':
			doColorChange_txt_timer = setInterval(this.frameset , interval);
		break;
		}
	}


	/**
	 * Method for cycle multiple colors
	 */
	this.doColorCycle = function(txt_bg,duration,fps/*[color1,color2,color3, ... , color_n]*/) {
		switch (txt_bg) {
		case 'bg':
			clearInterval (doColorCycle_bg_timer);
		break;
		case 'txt':
			clearInterval (doColorCycle_txt_timer);
		break;
		}

		var colors = new Array;
		var deltaframe = new Array;
		var arguments_array = new Array;
		arguments_array = arguments;
		var new_rgb;
		var interval = 1000 / fps;

		for (i = 3 ; i < arguments_array.length ; i++) {
			colors[i] = new Array;
			colors[i][0] = hex2Dec(arguments_array[i].substr(0,2));
			colors[i][1] = hex2Dec(arguments_array[i].substr(2,2));
			colors[i][2] = hex2Dec(arguments_array[i].substr(4,2));
		}

		var cont = 3;
		var initial_color = new Array;
		var final_color = new Array;
		var deltaframe = new Array;
		for (i = 0 ; i < 3 ; i++) {
			initial_color[i] = colors[cont][i];
			if ((cont + 1) < arguments_array.length) {
				final_color[i] = colors[cont+1][i];
			}
			else {
				final_color[i] = colors[3][i];
			}
			deltaframe[i] = (final_color[i] - initial_color[i]) * interval / duration;
		}

		var frames_number = fps * (duration / 1000);
		var actual_frame = 0;

		this.frameset = function() {
			if (actual_frame < frames_number) {
				new_rgb = '#'+dec2Hex(initial_color[0])+dec2Hex(initial_color[1])+dec2Hex(initial_color[2]);
				switch (txt_bg) {
					case 'bg':
						element.style.backgroundColor = new_rgb;
					break;
					case 'txt':
						element.style.color = new_rgb;
					break;
				}
				for (i = 0 ; i < 3 ; i++) {
					initial_color[i] += deltaframe[i];
				}
				actual_frame++;
			}
			else {
				cont = cont + 1;
				if (cont >= arguments_array.length) {
					cont = 3;
				}
				for (i = 0 ; i < 3 ; i++) {
					initial_color[i] = colors[cont][i];
					if ((cont + 1) < arguments_array.length) {
						final_color[i] = colors[cont+1][i];
					}
					else {
						final_color[i] = colors[3][i];
					}
					deltaframe[i] = (final_color[i] - initial_color[i]) * interval / duration;
				}
				actual_frame = 0;
			}
			return ('#'+dec2Hex(initial_color[0])+dec2Hex(initial_color[1])+dec2Hex(initial_color[2]));
		}

		switch (txt_bg) {
		case 'bg':
			doColorCycle_bg_timer = setInterval(this.frameset , interval);
		break;
		case 'txt':
			doColorCycle_txt_timer = setInterval(this.frameset , interval);
		break;
		}
	}

}

//-->

