using System;
using System.Text;

// Filename: Decay.cs
// Author:Sean Kessler
// Date:06/2003
//      11/2003 modified as Per W. Stanzl to alleviate problem with potential loss of precision

namespace MarketData.MarketDataModel
{
/// <summary>Decay - decay utility class</summary>
  public class Decay
  {
    private int days;
		private int applyDays;
    private float[] decays;
    private float seed;
    private const float SEED=.0116F; 

		public Decay(int days, float factor, int applyDays)
		{
			CreateDecay(factor, days, applyDays);
		}
	  public Decay(int days,float factor)
	  {
	    CreateDecay(factor,days, days);
	  }
    public Decay(int days)
    {
      CreateDecay(SEED,days, days);      
    }
    public float this[int day]
    {
      get{return decays[day];}
      set{decays[day]=value;}
    }
    public int Count
    {
      get{return decays.Length;}
    }
    public void Reverse()
    {
      float[] inverted=new float[this.decays.Length];
      for(int index=0;index<this.decays.Length;index++)
      {
        inverted[index]=this.decays[this.decays.Length-index-1];
      }
      decays=inverted;
    }
    public double[] ToDoubleReverse()
    {
      double[] decays=new double[this.decays.Length];
      for(int index=0;index<this.decays.Length;index++)
        decays[index]=this.decays[this.decays.Length-index-1];
      return decays;
    }
    public void CreateDecay(int days)
    {
      CreateDecay(seed,days);
    }
    public void CreateDecay(float seed,int days)
    {
			CreateDecay(seed, days, applyDays);
    }
		public void CreateDecay(float seed,int days, int applyDays)
		{
			this.seed=seed;
			this.days=days;
			this.applyDays=applyDays;
			decays=new float[days];

			if (days > 0)
			{
				decays[0] = 1F;
				if (applyDays > 0) decays[0] -= seed;
			
				for(int index=1;index<days;index++)
				{
					if (index < applyDays)
						decays[index]=(1.00F-seed)*decays[index-1]; 
					else
						decays[index] = decays[index-1];
				}
			}
			PostProcess();
		}
    public virtual void PostProcess()
    {
      return;
    }
    public float Seed
    {
      get{return seed;}
    }
    public int Days
    {
      get
      {
        return days;
      }
    }
		public int ApplyDays
		{
			get
			{
				return applyDays;
			}
		}
    public new string ToString()
    {
      StringBuilder sb=new StringBuilder();
      int length=Count;
      char[] crlf={'\r','\n'};

      for(int day=0;day<length;day++)
      {
        sb.Append(this[day].ToString()).Append(crlf);
      }
      return sb.ToString();
    }
  }
}
