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

namespace Intemi.InTrees
{
    class Tools
    {
        public static string MostCommonTarget(IDataTable dataTable)
        {
            IOneFeatureData tt = (dataTable as ITargets).Targets;
            int[] counts = tt.FeatureStatistics.counts;
            int maxi = 0;
            for (int i = 0; i < counts.Length; i++)
            {
                if (counts[i] > counts[maxi])
                {
                    maxi = i;
                }
            }

            //tt.FeatureEnumerator

            //tt.Features[maxi];
            //IVectorEnumerator t2 = tt.FeatureEnumerator();
            return (tt.FeatureInfo.Value(maxi));
        }

        public static int MajorityClass(IDataTable dataTable, ref bool shouldTerminate)
        {
            int majorityClass = -1;
            IOneFeatureData targets = (dataTable as ITargets).Targets;
            IFeature targetsInfo = targets.FeatureInfo; 
            if (targetsInfo == null)
                throw new ExceptionChochlik();

            IVectorEnumerator ve = targets.FeatureEnumerator();
            float[] classes = ve.Vector;
            ve.GoToInstance(0);
            int nrClasses = targetsInfo.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;

            return (majorityClass);
        }


        public static double Info(int[] counts)
        {
            int totalCount = 0;
            foreach (int count in counts)
            {
                totalCount += count;
            }
            return(Info(counts,totalCount));
        }

        public static double Info(int[] counts, int totalCount)
        {
            double[] d = new double[counts.Length];
            for(int i=0;i<counts.Length;i++)
            {
                d[i] = (double)counts[i] / totalCount; 
            }
            return (Entropy(d));
        }

        public static double Info(List<int[]> countsList)
        {
            int[] totalCount = new int[countsList.Count];
            int totalListCount=0;

            // wyliczamy ile jest wektorów w każdej z tablic i ile w całej liście
            int i = 0;
            foreach (int[] counts in countsList)
            {
                totalCount[i] = 0;
                foreach (int count in counts)
                    totalCount[i] += count;
                totalListCount += totalCount[i];
                i++;
            }

            double finalInfo = 0;
            i = 0;
            foreach (int[] counts in countsList)
            {                
                finalInfo += ((double)totalCount[i]/totalListCount)*Info(counts, totalCount[i]);
                i++;
            }

            return (finalInfo);          
        }

        public static double Entropy(double[] d)
        {
            double entrop = 0;
            foreach (double x in d)
            {
                if (x > 0) 
                 entrop += -(x) * Math.Log(x, 2);
            }
            return (entrop);
        }
    }

    
}
