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


namespace pmsDataGridView
{
    public class SoldBearing : Product
    {
        #region Constructor and Destructor
        
        public SoldBearing() { }

        public SoldBearing(Product b):base(b)
        {
            //this.copy(b);
            this.quantity = 0;
            //soldbearing = b;
            //soldbearing.quantity = 0; //reset the quantity

        }
        ~SoldBearing() { }

        #endregion

        //public enum SealType { OneSideMetal, BothSideMetal, OneSidePlastic, BothSidePlastic, BothSideMetalandPlastic }
        //public enum BrandType { Normal, NMB, NSK, KOYO, MIX }

      

        //Methods        
        //Variables        
        //public Bearing soldbearing;
        public double QtyPerMonth = 0;
        public double RevenuePerMonth = 0;
        public double RevenuePerYear = 0;
        public int frequency = 0;
        public double TotalRevenue = 0;  
        
    }

    public class SoldBearingList
    {
        #region Constructor and Distructor
        public SoldBearingList()
        {
            SoldBearinglist = new ArrayList();
        }
        ~SoldBearingList() { }
        #endregion

        #region Methods

        public void set_dates(DateTime start, DateTime end)
        {
            this.StartDate = start;
            this.EndDate = end;
        }
        public void reset(ProductList blist)
        {
            Revenue2 = 0;
            // match_bearing_index
            SoldBearinglist.Clear();

            //create an empty sold bearing list
            for (int i = 0; i < blist.Count; i++)
            { 
                SoldBearing sb = new SoldBearing(blist[i]);
                SoldBearinglist.Add(sb);
            }
        }

        private void include_from_sale(int sale_idx, ProductList bearinglist, SaleLogList salelist)
        {
            for (int i = sale_idx; i < salelist.Count; i++)
            {
                if (salelist[i].Date.CompareTo(this.StartDate) >= 0) //same or later than start date
                {
                    if (salelist[i].Date.CompareTo(this.EndDate) >= 0) //later than end date
                    {
                        break;
                    }
                    for (int j = 0; j < salelist[i].BearingOrder.Count; j++)
                    {
                        for (int k = 0; k < SoldBearinglist.Count; k++)
                        {
                            if (string.Compare(this[k].ID, salelist[i].BearingOrder[j].ID) == 0)
                            {
                                this[k].quantity += salelist[i].BearingOrder[j].quantity;
                                this[k].frequency += 1;
                                this[k].TotalRevenue += (salelist[i].BearingOrder[j].Price * salelist[i].BearingOrder[j].quantity);                                
                                break;
                            }
                        }
                    }
                    Revenue2 += salelist[i].Revenue;
                }
            }
            FinalSaleIndex = salelist.Count - 1;
            TimeSpan duration = EndDate - StartDate;
            TotalBearingSold = 0;
            TotalRevenue = 0;            
            RevenuePerMonth = 0;
            int ave_num_of_bearing = 0;
            double ave_revenue_per_month = 0;
            double ave_revenue_per_year = 0;
            for (int i = 0; i < SoldBearinglist.Count; i++)
            {
                ave_num_of_bearing = Convert.ToInt32(this[i].quantity * 30 / duration.TotalDays);
                this[i].QtyPerMonth = ave_num_of_bearing;
                ave_revenue_per_month = this[i].quantity * this[i].Price * 30 / duration.TotalDays;
                this[i].RevenuePerMonth = ave_revenue_per_month;
                ave_revenue_per_year = this[i].quantity * this[i].Price * 365 / duration.TotalDays;
                this[i].RevenuePerYear = ave_revenue_per_year;
                TotalBearingSold += this[i].quantity;
                TotalRevenue += this[i].TotalRevenue;                                
            }
            RevenuePerMonth = TotalRevenue * 30 / duration.TotalDays;
            RevenuePerYear = TotalRevenue * 365 / duration.TotalDays;
        }
        public void refresh_summary(ProductList bearinglist, SaleLogList salelist)
        {
            reset(bearinglist);
            include_from_sale(0, bearinglist, salelist);
        }

        public void up_to_date_summary(ProductList bearinglist, SaleLogList salelist)
        {//add new sales up to today to the existing summary stats.
            EndDate = DateTime.Now;
            include_from_sale(FinalSaleIndex + 1, bearinglist, salelist);
        }

        public void add(SoldBearing s)
        {
            SoldBearinglist.Add(s);
            s.Index = Count - 1;
        }

        public SoldBearing get_SaleLog(int location) //0 based index  
        {
            if (location < SoldBearinglist.Count)
            {
                return (SoldBearing)SoldBearinglist[location];
            }
            else return null;
        }

        public int Count
        {
            get { return SoldBearinglist.Count; }
        }

        public void remove(int location) //0 based index  
        {
            if (location < SoldBearinglist.Count)
            {
                SoldBearinglist.RemoveAt(location);
                
                for (int i = location; i < Count; i++) //decrement indices of salerecords after 'location' 
                {
                    this[i].Index--;
                }
                 
            }
            else return;
        }

        public void copy(SoldBearingList sample)
        {
            this.SoldBearinglist = sample.SoldBearinglist;
            this.StartDate = sample.StartDate;
            this.EndDate = sample.EndDate;
            this.TotalBearingSold = sample.TotalBearingSold;
            this.TotalRevenue = sample.TotalRevenue;
            this.RevenuePerMonth = sample.RevenuePerMonth;
            this.RevenuePerYear = sample.RevenuePerYear;
            this.FinalSaleIndex = sample.FinalSaleIndex;
            this.Revenue2 = sample.Revenue2;
        }

        //Indexer
        public SoldBearing this[int location]
        {
            get { return (SoldBearing)SoldBearinglist[location]; }
            set { SoldBearinglist[location] = value; }
        }

        [XmlIgnore]
        public string data_path
        {
            get { return FilePath; }
            set { FilePath = value; }
        }

        #endregion

        #region XML read and write methods

        [XmlElement("Bearing")]
        //this is a property, when use: item.items[0], returns an item
        public SoldBearing[] SaleRecords
        {
            get
            {
                SoldBearing[] salerecords = new SoldBearing[SoldBearinglist.Count];
                SoldBearinglist.CopyTo(salerecords);
                return salerecords;
            }

            set
            {
                if (value == null) return;
                SoldBearing[] salerecords = (SoldBearing[])value;
                SoldBearinglist.Clear();
                foreach (SoldBearing b in salerecords)
                {
                    SoldBearinglist.Add(b);
                }
            }
        } 

        public virtual void save()
        {

            // Serialization
            XmlSerializer ser = new XmlSerializer(typeof(SoldBearingList));
            TextWriter xml_write = new StreamWriter(FilePath);

            ser.Serialize(xml_write, this);
            xml_write.Close();
        }

        public virtual void load()
        {
            SoldBearingList temp = new SoldBearingList();
            // Deserialization

            XmlSerializer ser = new XmlSerializer(typeof(SoldBearingList));

            if (FilePath != null && File.Exists(FilePath))
            {
                TextReader xml_read = new StreamReader(FilePath);

                temp = (SoldBearingList)ser.Deserialize(xml_read);

                copy(temp);
                xml_read.Close();
            }
            else //dont find the xml file, so creat an empty sold bearing list anyway
            {
                copy(temp);
            }
        }

        #endregion

        #region Private variables

        private ArrayList SoldBearinglist;
        public DateTime StartDate;
        public DateTime EndDate;
        public int TotalBearingSold;
        public double TotalRevenue; //sum of all customer payables
        public double Revenue2; //revenue after trademe fee, shipping and discount
        public double RevenuePerMonth; //average
        public double RevenuePerYear; //average, or estimate if data is less than year
        public int FinalSaleIndex; //the final sale in salelog included in the stats
        private string FilePath = @"../../ProgramData/SoldItems.xml";

        #endregion
 
  

    }
}
