using System;
using System.Collections.Generic;
using Wayne.Lib;

namespace Wayne.ForecourtControl.Fusion
{
    public class FUSIONFuelPrice : IFuelPrice
    {
        // Fields
        public static int PriceGroupNumbersMin = 1;
        public static int PriceGroupNumbersMax = 11;
        private decimal basePrice;
        private decimal basePriceAsCurrency;
        private int fuelGrade;
        private decimal generalPriceDelta;
        private decimal generalPriceDeltaAsCurrency;
        private decimal maxPrice;
        private decimal minPrice;
        private FUSIONFuelPriceAddPricePerPriceGroup priceGroupDelta;
        private bool reserved;
        public Object locker;
        private bool changed = false;
        
        // Methods
        public FUSIONFuelPrice(int fuelGrade)
        {
            this.fuelGrade = fuelGrade;
            this.priceGroupDelta = new FUSIONFuelPriceAddPricePerPriceGroup(this);
            locker = new object();
        }

        internal void SetAddPrice(int priceGroup, decimal addPrice)
        {
            if (this.priceGroupDelta[priceGroup] != addPrice)
            {
                changed = true;
                this.priceGroupDelta[priceGroup] = addPrice;
            }
        }

        public bool Validate()
        {
            //for (int i = priceGroupDelta.PriceGroupNumbersMin; i <= priceGroupDelta.PriceGroupNumbersMax; i++)
            for (int i = FUSIONFuelPrice.PriceGroupNumbersMin; i <= FUSIONFuelPrice.PriceGroupNumbersMax; i++)
            {
                decimal num2 = (this.basePrice + this.generalPriceDelta) + this.priceGroupDelta[i];
                if ((num2 < this.minPrice) || (num2 > this.maxPrice))
                {
                    return false;
                }
            }
            return true;
        }

        // Properties
        public decimal BasePrice
        {
            get
            {
                return this.basePrice;
            }
            set
            {
                if (!this.reserved)
                {
                    throw new ObjectNotReservedException("Fuel prices not reserved.");
                }
                if (value != this.basePrice)
                {
                    changed = true;
                    this.basePrice = value;
                }
            }
        }

        public decimal BasePriceAsCurrency
        {
            get
            {
                return this.basePriceAsCurrency;
            }
            set
            {
                if (!this.reserved)
                {
                    throw new ObjectNotReservedException("Fuel prices not reserved.");
                }
                if (value != this.basePriceAsCurrency)
                {
                    changed = true;
                    this.basePriceAsCurrency = value;
                }
            }
        }

        public int FuelGrade
        {
            get
            {
                return this.fuelGrade;
            }
        }

        public decimal GeneralPriceDelta
        {
            get
            {
                return this.generalPriceDelta;
            }
            set
            {
                if (!this.reserved)
                {
                    throw new ObjectNotReservedException("Fuel prices not reserved.");
                }
                if (value != this.generalPriceDelta)
                {
                    changed = true;
                    this.generalPriceDelta = value;
                }
            }
        }

        public decimal GeneralPriceDeltaAsCurrency 
        {
            get { return this.generalPriceDeltaAsCurrency; }
            set
            {
                if (!this.reserved)
                {
                    throw new ObjectNotReservedException("Fuel prices not reserved.");
                }
                if (value != this.generalPriceDeltaAsCurrency)
                {
                    changed = true;
                    this.generalPriceDeltaAsCurrency = value;
                }
            } 
        }

        public IFuelPriceAddPricePerPriceGroup PriceGroupDelta
        {
            get { return this.priceGroupDelta; }
        }

        public bool Reserved
        {
            get { return this.reserved; }
        }

        public bool Changed
        {
            get { return this.changed; }
            set { changed = value; }
        }

        internal decimal WritableBasePrice
        {
            get { return this.basePrice; }
            set
            {
                if (value != this.basePrice)
                    changed = true;
                this.basePrice = value;
            }
        }

        internal decimal WritableGeneralPriceChange
        {
            get
            {
                return this.generalPriceDelta;
            }
            set
            {
                if (value != this.generalPriceDelta)
                    changed = true;
                this.generalPriceDelta = value;
            }
        }

        internal decimal WritableMaxPrice
        {
            get
            {
                return this.maxPrice;
            }
            set
            {
                this.maxPrice = value;
            }
        }

        internal decimal WritableMinPrice
        {
            get
            {
                return this.minPrice;
            }
            set
            {
                this.minPrice = value;
            }
        }

        internal bool WritableReserved
        {
            get
            {
                return this.reserved;
            }
            set
            {
                this.reserved = value;
                this.priceGroupDelta.Reserved = value;
            }
        }
    }

    public class FUSIONFuelPriceAddPricePerPriceGroup : IFuelPriceAddPricePerPriceGroup
    {
        // Fields
        private Dictionary<int, FUSIONPrice> priceDict = new Dictionary<int, FUSIONPrice>();
        private bool reserved;
        //public int priceGroupDeltaNum = 11;
        //public int PriceGroupNumbersMin;
        //public int PriceGroupNumbersMax;
        public int PriceGroupNumbers;
        //private bool changed = false;
        private FUSIONFuelPrice fp;

        // Methods
        public FUSIONFuelPriceAddPricePerPriceGroup(FUSIONFuelPrice _fp)
        {
            fp = _fp;
            //PriceGroupNumbersMin = Convert.ToInt16(1); //PriceGroup.MinValue; 
            //PriceGroupNumbersMax = Convert.ToInt16(9); //PriceGroup.MaxValue;  // TODO using pgrAppl7 arise an exception
            //PriceGroupNumbers = PriceGroupNumbersMax - PriceGroupNumbersMin + 1;
            PriceGroupNumbers = FUSIONFuelPrice.PriceGroupNumbersMax - FUSIONFuelPrice.PriceGroupNumbersMin + 1;
            //for (int i = 0; i <= this.PriceGroupNumbersMax; i++)
            for (int i = 0; i <= FUSIONFuelPrice.PriceGroupNumbersMax; i++)
            {
                this.priceDict.Add(i, new FUSIONPrice(0M, false));
            }

        }

        // Properties
        internal decimal this[int priceGroup]
        {
            get
            {
                return this.priceDict[priceGroup].price;
            }
            set
            {
                if (this.priceDict[priceGroup].price != value)
                {
                    this.priceDict[priceGroup].price = value;
                    this.priceDict[priceGroup].changed = true;
                }
            }
        }

        internal bool Reserved
        {
            get
            {
                return this.reserved;
            }
            set
            {
                this.reserved = value;
            }
        }

        public bool getChanged(int priceGroup)
        { 
            return this.priceDict[priceGroup].changed; 
        }
        public void setChanged(int priceGroup, bool value) 
        { 
            this.priceDict[priceGroup].changed = value; 
        }

        decimal IFuelPriceAddPricePerPriceGroup.this[int priceGroup]
        {
            get
            {
                return this.priceDict[priceGroup].price;
            }
            set
            {
                if (!this.reserved)
                {
                    throw new ObjectNotReservedException("Fuel prices not reserved.");
                }
                if (value != this.priceDict[priceGroup].price)
                {
                    fp.Changed = true;
                    this.priceDict[priceGroup].price = value;
                    this.priceDict[priceGroup].changed = true;
                }
            }
        }
    }

    public class FUSIONPrice
    {
        public decimal price;
        public bool changed;

        public FUSIONPrice(decimal _price, bool _changed)
        {
            price = _price;
            changed = _changed;
        }
    }
}