
	var artMooChart = new Class({
	
		Implements : [ Events, Options ],
	
		options :
		{
			'chartWidth' : 640,
			'chartHeight' : 240,
			'chartClass' : 'apfChart',
			'animated' : false,
			'opacity' : 0.90,
			'tips' : true,
			'animation' : 
			{
				'comein' : 'bottom',
				'duration' : 750,
				'fps' : 75,
				'fx' : Fx.Transitions.Quad.easeOut,
				'opacity_start' : 0.01
			},
			'layout' :
			{
				'bar_pad_top' : 10,
				'axis_overlap' : true,
				'x_axis' : true,
				'x_axis_height' : 25,
				'x_axis_text' : '&nbsp;',
				'y_axis' : true,
				'y_axis_width' : 32,
				'y_axis_use_steps' : true,
				'y_axis_steps' : 10,
				'y_axis_text' : '&nbsp;',
				'bar_spacing' : 10
			},
			'bars' :
			{
			}
		},
		
		barStack :
		{
		},
	
		initialize: function( options )
		{
			if(!options || !options.targetID) return false;

			if(!$(options.targetID))
			{
				alert('Target Container not found (' + options.targetID + ')');
				return false;
			}

			this.setOptions(this.options, options);

			if( !this.options.layout.x_axis )
			{
				this.options.layout.x_axis_height = 0;
			}

			if( !this.options.layout.y_axis )
			{
				this.options.layout.y_axis_width = 0;
			}

			this.setup_Container();

			if( this.chart_Container )
			{
				this.setup_Axis();
				this.setup_ChartDisplay();
				this.setup_Bars();
			}
			else
			{
				alert('Chart coult not be setup.');
				return false;
			}

		},

	/*
	 *  -------------------------------------------------------
	 *  Setup main container which will hold all the
	 *  other DOM nodes of out chart
	 *  -------------------------------------------------------
	 */

		setup_Container: function()
		{
			$(this.options.targetID).empty().setStyles(
				{
				'width' : this.options.chartWidth.toInt() + 'px',
				'height' : this.options.chartHeight.toInt() + 'px',
				'display' : 'block'
				}
			);

			new Element(
				'div',
				{
					'id' : 'artMooChart_' + (this.options.targetID)+'_Container',
					'class' : this.options.chartClass,
					'styles' :
					{
						'z-index' : 100000,
						'position' : 'relative',
						'display' : 'block',
						'overflow' : 'hidden',
						'width' : this.options.chartWidth.toInt() + 'px',
						'height' : this.options.chartHeight.toInt() + 'px'
					}
				}
			).inject($(this.options.targetID),'inside');
			
			if( $('artMooChart_' + (this.options.targetID)+'_Container') )
			{
				this.chart_Container = $('artMooChart_' + (this.options.targetID)+'_Container');
			}
		},

	/*
	 *  -------------------------------------------------------
	 *  Setup the chart itself (the bars) surrounded by the
	 *  possible x/y axis nodes
	 *  -------------------------------------------------------
	 */

		setup_ChartDisplay : function()
		{
			new Element(
				'div',
				{
					'id' : 'artMooChart_' + (this.options.targetID)+'_Display',
					'class' : this.options.chartClass+'-display',
					'styles' :
					{
						'z-index' : 100001,
						'position' : 'absolute',
			 			'display' : 'block',
						'overflow' : 'hidden',
			 			'left' : this.options.layout.y_axis_width.toInt() + 'px',
			 			'top' : '0px',
						'width' : ( this.options.chartWidth.toInt() - this.options.layout.y_axis_width.toInt() ) + 'px',
						'height' : ( this.options.chartHeight.toInt() - this.options.layout.x_axis_height.toInt() ) + 'px'
					}
				}
			).inject(this.chart_Container,'inside');

			if( $('artMooChart_' + (this.options.targetID)+'_Display') && this.options.layout.y_axis_use_steps)
			{
				this.stepHeight = ( this.options.chartHeight.toInt() - this.options.layout.x_axis_height.toInt() ) / this.options.layout.y_axis_steps.toInt();

				for( var sX = 1; sX < this.options.layout.y_axis_steps.toInt(); sX++ )
				{
					new Element(
						'div',
						{
							'class' : this.options.chartClass+'-display-y-axis-step',
							'styles' :
							{
								'z-index' : 100002,
								'position' : 'absolute',
					 			'display' : 'block',
								'overflow' : 'hidden',
								'opacity' : 0.5,
					 			'left' : this.options.layout.y_axis_width.toInt() + 'px',
					 			'top' : (sX * this.stepHeight).toInt() + 'px',
								'width' : ( this.options.chartWidth.toInt() - this.options.layout.y_axis_width.toInt() ) + 'px'
							}
						}
					).inject(this.chart_Container,'inside');
				}
			}
			
		},

	/*
	 *  -------------------------------------------------------
	 *  Setup optional X/Y axis nodes
	 *  -------------------------------------------------------
	 */

		setup_Axis: function()
		{
			if( this.options.layout.x_axis )
			{
				new Element(
					'div',
					{
						'class' : this.options.chartClass+'-x-axis',
						'html' : this.options.layout.x_axis_text,
						'styles' :
						{
							'z-index' : 100003,
							'position' : 'absolute',
				 			'display' : 'block',
							'overflow' : 'hidden',
				 			'left' : '0px',
				 			'top' : (this.options.chartHeight.toInt() - this.options.layout.x_axis_height.toInt()) + 'px',
							'width' : this.options.chartWidth.toInt() + 'px',
							'height' : this.options.layout.x_axis_height.toInt() + 'px'
						}
					}
				).inject(this.chart_Container,'inside');
			}

			if( this.options.layout.y_axis )
			{
				new Element(
					'div',
					{
						'class' : this.options.chartClass+'-y-axis',
						'html' : this.options.layout.y_axis_text,
						'styles' :
						{
							'z-index' : 100003,
							'position' : 'absolute',
				 			'display' : 'block',
							'overflow' : 'hidden',
				 			'left' : '0px',
				 			'top' : '0px',
							'width' : this.options.layout.y_axis_width.toInt() + 'px',
							'height' : (this.options.chartHeight.toInt() - this.options.layout.x_axis_height.toInt() + (this.options.layout.axis_overlap ? 1 : 0) ) + 'px'
						}
					}
				).inject(this.chart_Container,'inside');
				
			}

		},
		
	/*
	 *  -------------------------------------------------------
	 *  Setup the chart-bars with preflight check (validity)
	 *  -------------------------------------------------------
	 */

		setup_Bars: function()
		{
			var bars = barheight = maxValue = 0;

			for( bar in this.options.bars )
			{
				bars++;
				if( !this.options.bars[bar].value )
				{
					alert('Bar ' + bars + ' has no value');
				//	this.options.bars[bar].value = 0;
					return false;
				}
				else
				{
					if( !this.options.bars[bar].classname || this.options.bars[bar].classname == '' )
					{
						this.options.bars[bar].classname = '-bar';
					}
					maxValue = Math.max(maxValue,this.options.bars[bar].value);
				}
			}

			if( bars > 0 )
			{
				dispWidth = (this.options.chartWidth.toInt() - this.options.layout.y_axis_width.toInt() - ((bars + 1) * this.options.layout.bar_spacing.toInt())).toInt();
				barWidth = (dispWidth / bars).toInt();
				availableHeight	= this.options.chartHeight.toInt() - this.options.layout.x_axis_height.toInt() - this.options.layout.bar_pad_top.toInt();

				barcount = 0;

				for( bar in this.options.bars )
				{
					thisBarHeight = Math.ceil( (availableHeight / maxValue) * this.options.bars[bar].value );
					thisBarTopPad = (availableHeight - thisBarHeight + this.options.layout.bar_pad_top.toInt()).toInt();
					posFromLeft = (this.options.layout.y_axis_width.toInt() + ((barcount+1)*this.options.layout.bar_spacing.toInt()).toInt() + (barcount * barWidth)).toInt();

					barLeftPosInit	= posFromLeft;
					barTopPosInit	= (this.options.animated ? availableHeight : thisBarTopPad);

					CI = this.options.bars[bar].comein ? this.options.bars[bar].comein : this.options.animation.comein;

					switch( CI )
					{
						case 'left' :
							barLeftPosInit	= barWidth *-1;
							break;
						case 'right' :
							barLeftPosInit	= dispWidth + barWidth;
							break;
						case 'top' :
							barTopPosInit	= thisBarHeight *-1;
							break;
						default :
							break;
					}

					this.barStack[bar] = new Element(
						'div',
						{
							'class' : this.options.chartClass + this.options.bars[bar].classname,
							'id' : this.options.chartClass + '-DataBar-'+barcount,
							'html' : this.options.bars[bar].label ? '<span class="'+(this.options.chartClass + this.options.bars[bar].classname+'-label')+'">' + this.options.bars[bar].label + '</span><br>' + this.options.bars[bar].value : this.options.bars[bar].value,
							'styles' :
							{
								'z-index' : 100002,
								'position' : 'absolute',
					 			'display' : 'block',
								'overflow' : 'hidden',
								'opacity' : this.options.opacity,
								'visibility' : 'visible',
					 			'left' : barLeftPosInit + 'px',
					 			'top' : barTopPosInit + 'px',
								'height' : thisBarHeight + 'px',
								'width' : barWidth + 'px'
							}
						}
					).inject(this.chart_Container,'inside');

					if( this.options.animated )
					{
						var barFX = new Fx.Morph($(this.options.chartClass + '-DataBar-'+barcount),
							{
								duration: this.options.animation.duration,
								fps : this.options.animation.fps,
								transition: this.options.animation.fx
							}
						).start(
							{
							'left' : posFromLeft + 'px',
							'top' : thisBarTopPad + 'px',
							'opacity' : this.options.opacity 
							}
						);
					}

					if( this.options.tips )
					{
						barObj = $(this.options.chartClass + '-DataBar-'+barcount);
						barObj.store('tip:title', this.options.bars[bar].label ? this.options.bars[bar].label : this.options.bars[bar].value);   
						barObj.store('tip:text', this.options.bars[bar].value);
						barObj.addClass(this.options.chartClass + '-tips');
					}

					barcount++;

				}

				if( this.options.tips )
				{
					this.barTips = new Tips('.'+this.options.chartClass+'-tips',
						{
							className: 'tip',
							fixed: false,
							hideDelay: 0,
							showDelay: 0
						}
					);

					this.barTips.addEvents({
						'show' : function(tip)
							{
								tip.setStyle('opacity', 0.90);
							},
						'hide': function(tip)
							{
								tip.setStyle('opacity', 0.01);
							}   
						}
					);
				}
			}
		}
	});
	
