using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Xml;

using DairyTuner.TMR.Data;

namespace DairyTuner.TMR
{
    public class AppManager
    {
        private List<RationConfig> m_lstRations = new List<RationConfig>();
        private List<String> m_lstFeeders = new List<string>();
        private String m_sSelFeeder = String.Empty;

        private static AppManager m_Current;
        
        public static AppManager Current
        {
            get 
            {
                if (m_Current == null)
                    m_Current = new AppManager();

                return m_Current; 
            }
        }

        public static readonly string DataDir = AppFolder + @"\data";

        public static string AppFolder
        {
            get
            {
                return Path.GetDirectoryName(
                         Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
            }
        }

        public List<RationConfig> Rations
        {
            get { return m_lstRations; }
        }

        public List<String> Feeders
        {
            get { return m_lstFeeders; }
        }

        public void SetFeeder(String feeder)
        {
            m_sSelFeeder = feeder;
        }

        public String CurrentFeeder
        {
            get { return m_sSelFeeder; }
        }

        public void AddRation(RationConfig ration)
        {
            m_lstRations.Add(ration);
        }

        public void AddFeeder(String feeder)
        {
            m_lstFeeders.Add(feeder);
        }

        public RationConfig FindRation(String name)
        {
            foreach (RationConfig ration in m_lstRations)
            {
                if (ration.Name == name)
                    return ration;
            }
            return null;
        }
        public void Load()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(AppManager.DataDir + RationConfig.FileName);

            XmlElement nodeRoot = doc.DocumentElement;
            foreach (XmlNode node in nodeRoot.ChildNodes)
            {
                if (node.Name == "Ration")
                {
                    RationConfig ration = new RationConfig();
                    ration.Parse(node);

                    AddRation(ration);
                }
                else if (node.Name == "Pen")
                {
                    String name = node.Attributes["orderid"].Value;

                    PenConfig pen = new PenConfig();
                    pen.Parse(node);

                    RationConfig ration = FindRation(name);
                    if(ration != null)
                        ration.AddPen(pen);
                }
                else if (node.Name == "Feeder")
                {
                    ParseFeeders(node);
                }
            }
        }

        private void ParseFeeders(XmlNode nodeParent)
        {
            foreach (XmlNode node in nodeParent.ChildNodes)
            {
                if (node.Name == "FeederName")
                {
                    AddFeeder(node.InnerText);
                }
            }
        }

        public float CalRationAmountFed(RationConfig ration)
        {
            if (ration == null)
                return 0;

            float amountFed = 0;
            foreach (PenConfig pen in ration.Pens)
                amountFed += CalPenAmountFed(pen);

            return amountFed;
        }

        public float CalPenAmountFed(PenConfig pen)
        {
            if (pen == null)
                return 0;

            return pen.ActualCows * pen.AmountFed;
        }

        public int CountCows(RationConfig ration)
        {
            if (ration == null)
                return 0;

            int cows = 0;
            foreach (PenConfig pen in ration.Pens)
                cows += pen.ActualCows;

            return cows;
        }

        public float SumIngredients(RationConfig ration)
        {
            float amount = 0;
            foreach (IngredientConfig ingre in ration.Ingredients)
                amount += ingre.Amount;

            return amount;
        }

        public float CalIngredientAmount(RationConfig ration, IngredientConfig ingre)
        {
            int timeFed = ration.TimeFed;
            if (ration.TimeFed == 0)
                return 0;

            float amountFed = CalRationAmountFed(ration);
            float totalIngredients = SumIngredients(ration);
            return amountFed / totalIngredients * ingre.Amount / timeFed;
        }
    }
}
