using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FLY.Thick.Base.Server
{


    public class TempFilter
    {
        DateTime sampleTime;
        int sampleFailure;
        int swfilterCnt;

        class SWFilter
        {
            int[] buffer;
            int bufferSize;
            int lastData;
            int initvalue;

            public SWFilter(int buffersize)
            {
                this.bufferSize = buffersize;

                buffer = new int[buffersize];
            }

            public int CalValue(int window)
            {
                double sum = 0;
                int cnt = 0;
                int p = lastData;
                while (window > 0)
                {
                    if (buffer[p] != initvalue)
                    {
                        sum += buffer[p];
                        cnt++;
                    }
                    p--;
                    if (p < 0) p = bufferSize - 1;
                    window--;
                }
                if (cnt == 0) return initvalue;
                return (int)(sum / cnt + 0.5);
            }

            public void Clear(int initvalue)
            {
                for (int i = 0; i < bufferSize; i++)
                    buffer[i] = initvalue;
                this.initvalue = initvalue;
                lastData = bufferSize - 1;
            }

            public void PushData(int value)
            {
                lastData++;
                if (lastData >= bufferSize)
                    lastData = 0;
                buffer[lastData] = value;
            }

            public void SetSize(int buffersize) 
            {
                if (buffersize != this.bufferSize) 
                {
                    this.bufferSize = buffersize;

                    buffer = new int[buffersize];

                    Clear(initvalue);
                }
            }
        }
        SWFilter swfilter;
        int tempBIndex;
        int[] tempBuf = new int[3];
        int preValue;

        public TempFilter()
        {
            sampleFailure = 0;
            swfilterCnt = 3;
            tempBIndex = -1;
            swfilter = new SWFilter(50);
            swfilter.Clear(-1);
            preValue = -1;
        }

        public void ResetSampleFailure()
        {
            sampleFailure = 0;
        }
        public bool IsSampleFailure()
        {
            if (sampleFailure < 0) return true;
            return false;
        }
        public int CalSampleAD(int ad) 
        {
            int originAD;
            return CalSampleAD(ad, out originAD);
        }
        public int CalSampleAD(int ad, out int originAD)
        {
            originAD = 0;
            int delta;
            TimeSpan ts = TimeSpan.MaxValue;
            DateTime dt = DateTime.Now;

            switch (sampleFailure)
            {
                case 0:
                    sampleTime = dt;
                    sampleFailure = 1;
                    break;
                default:
                    dt = DateTime.Now;
                    ts = dt.Subtract(sampleTime);
                    sampleTime = dt;
                    break;
            }
            if ((ts.TotalMinutes > 30) || (preValue < 0))
            {
                preValue = ad;
                tempBIndex = -1;
                swfilter.Clear(-1);
                swfilter.PushData(preValue);

                originAD = ad;
                return ad;
            }
            delta = Math.Abs(ad - preValue);

            if (delta > 0.01 * Math.Abs(preValue))//跳到超过 1% ，有问题
            {
                if (tempBIndex < 1)		// Sudden Changed! Need 3 times to confirm.
                {
                    tempBIndex++;
                    tempBuf[tempBIndex] = ad;
                    return (int)preValue;
                }
                else
                {
                    preValue = ad;
                    sampleFailure = -1;
                    swfilter.Clear(-1);
                    swfilter.PushData(preValue);
                    originAD = ad;
                    return ad;
                }
            }
            //2013.04.19
            //
            //	if( delta > 0.008*preValue )trustFactor = 0.14;
            //	else if( delta > 0.006*preValue )trustFactor = 0.175;
            //	else if( delta > 0.004*preValue )trustFactor = 0.23;
            //	else if( delta > 0.002*preValue )trustFactor = 0.35;
            //	else if( delta > 0.001*preValue )trustFactor = 0.6;
            //	else trustFactor = 0.9;
            //	if( originAD )*originAD = (long)(preValue + delta * sign * trustFactor + 0.5);
            //	SWFilterPushData( swfilter, (long)(preValue + delta * sign * trustFactor + 0.5));
            //	preValue = ExponentialFilter( preValue, preValue+delta*sign*trustFactor, sysParam.swfilterConst );
            ////	preValue = (double)CalSWFilterValue( swfilter, 10 );

            tempBIndex = -1;
            //2013.04.19	
            originAD = ad;
            swfilter.PushData(ad);
            preValue = swfilter.CalValue(swfilterCnt);
            return preValue;
        }
        public void SetWindow(int window) 
        {
            if (window < 50)
                swfilterCnt = window;
        }
    }
}
