context: using System;
  using System.Collections;
  
  namespace Server.Engines.Reports
  {
  	public enum BarGraphRenderMode
  	{
  		Bars,
  		Lines
  	}
  
  	public class BarGraph : Chart
  	{
  		#region Type Identification
  		public static readonly PersistableType ThisTypeID = new PersistableType( "bg", new ConstructCallback( Construct ) );
  
  		private static PersistableObject Construct()
  		{
  			return new BarGraph();
  		}
  
  		public override PersistableType TypeID{ get{ return ThisTypeID; } }
  		#endregion
  
  		private int m_Ticks;
  		private BarGraphRenderMode m_RenderMode;
  
  		private string m_xTitle;
  		private string m_yTitle;
  
  		private int m_FontSize = 7;
  		private int m_Interval = 1;
  
  		private BarRegion[] m_Regions;
  
  		public int Ticks{ get{ return m_Ticks; } set{ m_Ticks = value; } }
  		public BarGraphRenderMode RenderMode{ get{ return m_RenderMode; } set{ m_RenderMode = value; } }
  
  		public string xTitle{ get{ return m_xTitle; } set{ m_xTitle = value; } }
  		public string yTitle{ get{ return m_yTitle; } set{ m_yTitle = value; } }
  
  		public int FontSize{ get{ return m_FontSize; } set{ m_FontSize = value; } }
  		public int Interval{ get{ return m_Interval; } set{ m_Interval = value; } }
  
  		public BarRegion[] Regions{ get{ return m_Regions; } set{ m_Regions = value; } }
  
  		public BarGraph( string name, string fileName, int ticks, string xTitle, string yTitle, BarGraphRenderMode rm )
  		{
  			m_Name = name;
  			m_FileName = fileName;
  			m_Ticks = ticks;
  			m_xTitle = xTitle;
  			m_yTitle = yTitle;
  			m_RenderMode = rm;
  		}
  
  		private BarGraph()
  		{
  		}
  
  		public override void SerializeAttributes( PersistanceWriter op )
  		{
  			base.SerializeAttributes( op );
  
  			op.SetInt32( "t", m_Ticks );
  			op.SetInt32( "r", (int) m_RenderMode );
  
  			op.SetString( "x", m_xTitle );
  			op.SetString( "y", m_yTitle );
  
  			op.SetInt32( "s", m_FontSize );
  			op.SetInt32( "i", m_Interval );
  		}
  
  		public override void DeserializeAttributes( PersistanceReader ip )
  		{
  			base.DeserializeAttributes( ip );
  
  			m_Ticks = ip.GetInt32( "t" );
  			m_RenderMode = (BarGraphRenderMode) ip.GetInt32( "r" );
  
  			m_xTitle = ip.GetString( "x" );
  			m_yTitle = ip.GetString( "y" );
  
  			m_FontSize = ip.GetInt32( "s" );
  			m_Interval = ip.GetInt32( "i" );
  		}
  
  		public static int LookupReportValue( Snapshot ss, string reportName, string valueName )
  		{
  			for ( int j = 0; j < ss.Children.Count; ++j )
  			{
  				Report report = ss.Children[j] as Report;
  
  				if ( report == null || report.Name != reportName )
  					continue;
  
  				for ( int k = 0; k < report.Items.Count; ++k )
  				{
  					ReportItem item = report.Items[k];
  
  					if ( item.Values[0].Value == valueName )
  						return Utility.ToInt32( item.Values[1].Value );
  				}
  
  				break;
  			}
  
  			return -1;
  		}
  
  		public static BarGraph DailyAverage( SnapshotHistory history, string reportName, string valueName )
  		{
  			int[] totals = new int[24];
  			int[] counts = new int[24];
  
  			int min = history.Snapshots.Count - (7 * 24); // averages over one week
  
  			if ( min < 0 )
  				min = 0;
  
  			for ( int i = min; i < history.Snapshots.Count; ++i )
  			{
  				Snapshot ss = history.Snapshots[i];
  
  				int val = LookupReportValue( ss, reportName, valueName );
  
  				if ( val == -1 )
  					continue;
  
  				int hour = ss.TimeStamp.TimeOfDay.Hours;
  
  				totals[hour] += val;
  				counts[hour]++;
  			}
  
  			BarGraph barGraph = new BarGraph( "Hourly average " + valueName, "graphs_" + valueName.ToLower() + "_avg", 10, "Time", valueName, BarGraphRenderMode.Lines );
  
  			barGraph.m_FontSize = 6;
  
  			for ( int i = 7; i <= totals.Length+7; ++i )
  			{
  				int val;
  
  				if ( counts[i%totals.Length] == 0 )
  					val = 0;
  				else
  					val = (totals[i%totals.Length] + (counts[i%totals.Length] / 2)) / counts[i%totals.Length];
  
  				int realHours = i%totals.Length;
  				int hours;
  
  				if ( realHours == 0 )
  					hours = 12;
  				else if ( realHours > 12 )
  					hours = realHours - 12;
  				else
  					hours = realHours;
  
  				barGraph.Items.Add( hours + (realHours >= 12 ? " PM" : " AM"), val );
  			}
  
  			return barGraph;
  		}
  
  		public static BarGraph Growth( SnapshotHistory history, string reportName, string valueName )
  		{
  			BarGraph barGraph = new BarGraph( "Growth of " + valueName + " over time", "graphs_" + valueName.ToLower() + "_growth", 10, "Time", valueName, BarGraphRenderMode.Lines );
  
  			barGraph.FontSize = 6;
  			barGraph.Interval = 7;
  
  			DateTime startPeriod = history.Snapshots[0].TimeStamp.Date + TimeSpan.FromDays( 1.0 );
  			DateTime endPeriod = history.Snapshots[history.Snapshots.Count - 1].TimeStamp.Date;
  
  			ArrayList regions = new ArrayList();
  
  			DateTime curDate = DateTime.MinValue;
  			int curPeak = -1;
  			int curLow  = 1000;
  			int curTotl = 0;
  			int curCont = 0;
  			int curValu = 0;
  
  			for ( int i = 0; i < history.Snapshots.Count; ++i )
  			{
  				Snapshot ss = history.Snapshots[i];
  				DateTime timeStamp = ss.TimeStamp;
  
  				if ( timeStamp < startPeriod || timeStamp >= endPeriod )
  					continue;
  
  				int val = LookupReportValue( ss, reportName, valueName );
  
  				if ( val == -1 )
  					continue;
  
  				DateTime thisDate = timeStamp.Date;
  
  				if ( curDate == DateTime.MinValue )
  					curDate = thisDate;
  
  				curCont++;
  
gt: 				curTotl += val;