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

namespace Intemi
{
    public class MajorityConfig : IConfiguration
    {
        public void Configure(ConfigBuilder confBuilder)
        {
            confBuilder.DeclareInput("Dataset",
                new Type[] { typeof(IDataSet), typeof(ITargets) });
            confBuilder.DeclareOutput("Classifier", null,
                new Type[] { typeof(IClassifier) });
        }
        public object Clone() { return new MajorityConfig(); }
    }

    [Machine("Majority classifier",typeof(MajorityConfig))]
    public class Majority : IMachine, IClassifier
    {
        IMachineBase machineBase;
        public void SetMachineBase(IMachineBase _machineBase)
        {
            machineBase = _machineBase;
        }

        int majorityClass = -1;

        public void Run(ref bool shouldTerminate)
        { 
            IDataSet dataset;

            majorityClass = -1; 
            
            dataset = machineBase.GetInput("Dataset") as IDataSet;
            IOneFeatureData targets = (dataset as ITargets).Targets;

            IVectorEnumerator  ve = targets.FeatureEnumerator();
            float[] classes = ve.Vector;
            ve.GoToInstance(0);
            int nrClasses = targets.FeatureInfo.NrValues;
            double[] clStat = new double[nrClasses];

            for (int i = 0; !shouldTerminate && i < classes.Length; i++)
                clStat[(int)classes[i]]++;
            
            majorityClass = 0;
            for (int i = 1; !shouldTerminate && i < nrClasses; i++)
                if (clStat[i] > clStat[majorityClass])
                    majorityClass = i;

            if (shouldTerminate)
                majorityClass = -1;
        }
        IOneFeatureData IClassifier.Classify(IDataSet dataSetToClassify)
        {
            IDataSet dataSet = machineBase.GetInput("Dataset") as IDataSet;
            IOneFeatureDataBuilder dtb = ((ITargets)dataSet).Targets.CopyStructure(dataSetToClassify.InstanceCount);

            for (int i = 0; i < dataSetToClassify.InstanceCount; i++)
                dtb.AddValue(majorityClass);

            return (IOneFeatureData)dtb.Build();
        }
        bool IClassifier.VerifyTestData(IDataSet d)
        {
            return true;
        }
    }
}
