using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.Interface.HSViewer;
using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;

using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Controller;

using CommonMP.HYMCO.CoreImpl.Data;

using CommonMP.HYMCO.CoreOptionl.HymcoExpansionModel;

namespace CommonMP.HYMCO.Ocean.McOceanBaseModel
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class MzCashflowModelElementCalInfo : McInterCnnctModelCalInfo
    {
        // 計算用データの変数
        /// <summary>設備  [億円]</summary>
        public double m_Facility = 100.0;
        /// <summary>減価償却率 :年利(1～0) </summary>
        public double m_DepreciationRate = 0.03;

        /// <summary>累積：負債 [億円]</summary>
        public double m_Debt = 100.0;
        /// <summary>（負債と返却）利率:年利(1～0)</summary>
        public double m_DebtInterestRate = 0.03;

        /// <summary>累積：債権 [億円]</summary>
        public double m_Credit = 0;
        /// <summary>債権利率:年利(1～0)</summary>
        public double m_CreditInterestRate = 0.03;

        /// <summary>累積：自己資本 [億円]</summary>
        public double m_CapitalStock = 0.0;
        /// <summary>自己手持ちキャッシュ [億円]</summary>
        public double m_Chash = 100.0;

        /// <summary>非物質価値  [億円]</summary>
        public double m_NonMaterial_Val = 0;
        /// <summary>期間内の　収入  [億円]</summary>
        //public double m_Income = 0;
        /// <summary>期間内の　支出  [億円]</summary>
        //public double m_Expense = 0;
        /// <summary>　利益： </summary>
        public double m_Benefit = 0;

        /// <summary> 変動コスト [億円]</summary>
        public double m_DriftCost = 0;

        //----------------------------------------
        /// <summary>債務不履行フラグ  </summary>
        public int Default_FLG = 0;

        //------------ 物品売買用 ------------------
        // 例えば、原料の購入、製品の販売等
        /// <summary> 購入資材・原料  [ｔ]  製品を生産するために使用するもの</summary>
        public double m_Materials = 0;
        /// <summary> 購入資材・原料単価</summary>
        public double m_MaterialsUnitCost = 0;
        /// <summary> 次回購入予定額 　　億円 </summary>
        public double m_dNextDealingChash = 0;
        /// <summary> 製品の量  [ｔ] 生産したもの:売るもの</summary>
        public double m_dProduct = 0;
        /// <summary> 購入・小売り単価 　　万円／小売り単位 </summary>
        public double m_dPrductUnitCost = 1;
        /// <summary> 供給能力  [ｔ] </summary>
        public double m_dFeedCapability = 0;
        /// <summary> 購買用意金 　　億円 </summary>
        public double m_dDealingChash = 0;
        /// <summary> 自分が売り手の時の受注額　　億円 </summary>
        public double m_dProductNextOrder = 0;

        //------------ 非物品売買用 ------------------
        // 例えば、観測、海洋警備活動等
        /// <summary>購入・小売り価格 　　万円／小売り単位 </summary>
        public double m_dNowUnitPlace = 0;
        /// <summary> 発注　億円 </summary>
        public double m_OrdersPlaced = 0;
        /// <summary> 支払い　億円 </summary>
        public double m_Payment = 0;
        /// <summary> 請求　億円 </summary>
        public double m_Claimed = 0;
        /// <summary> 見積もり　億円 </summary>
        public double m_EstimatedCost = 0;
        /// <summary> 生産への直接寄与率：例えば調査データは＝１、海上警備行動は、直接生産を生み出さないので＝０ </summary>
        public double m_ContributionRatioForProduct = 1.0;

        //----------------------------------------
        /// <summary> 人間の行為間隔  </summary>
        public double m_HmnActTimeSpan = 24 * 3600;
        /// <summary> 時間経過：ワーク用  </summary>
        public double m_WorkTime = 0;

        //----------------------------------------
        /// <summary>要求O2</summary>
        public double m_HmnReqO2 = 0.0;
        /// <summary>受け取ったO2</summary>
        public double m_HmnRcvO2 = 0.0;
        /// <summary> 排出CO2:（単位生産量・単位活動当たり）</summary>
        public double m_HmnCO2Emission = 0.0;
        /// <summary> １日当たりの排出CO2 Kg/Day </summary>
        public double m_HmnCO2EmissionDay = 0.0;

        public virtual void Clear()
        {
            m_Facility = 0;
            //m_DepreciationRate = 0;

            m_CapitalStock = 0;
            m_Chash = 0;

            m_Debt = 0;
            //m_DebtInterestRate = 0;
            m_Credit = 0;
            //m_CreditInterestRate = 0;

            //m_Income = 0;
            //m_Expense = 0;
            m_NonMaterial_Val = 0;
            m_Benefit = 0;
            m_DriftCost = 0;

            Default_FLG = 0;
            m_dDealingChash = 0;
            m_dNextDealingChash = m_dDealingChash;
            m_Materials = 0;
            m_dFeedCapability = 0;
            m_dProduct = 0;
            m_dProductNextOrder = 0;

            m_dNowUnitPlace = 0;
            m_OrdersPlaced = 0;
            m_EstimatedCost = 0;
            m_Payment = 0;
            m_Claimed = 0;
        }

        /// <summary><para>method outline:</para>
        /// <para>自己複製</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Clone( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>同一内容で　別院スタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>収束演算時、特定の時刻に状態を戻す場合等に使用する</para>
        /// </remarks>
        public override McCalInfo Clone()
        {
            MzCashflowModelElementCalInfo csRtn = new MzCashflowModelElementCalInfo();
            csRtn.CopyInfo(this);
            return csRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>引数で与えられた情報を自分にコピーを行う</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = CopyInfo(csOrgInfo) </para>
        /// </example>
        /// <param name="csOrgInfo">コピー元情報</param>
        /// <returns> bool true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool CopyInfo(McCalInfo csOrgInfo)
        {
            MzCashflowModelElementCalInfo csOrgDt = (MzCashflowModelElementCalInfo)csOrgInfo;
            base.CopyInfo(csOrgInfo);

            m_Facility = csOrgDt.m_Facility;
            m_DepreciationRate = csOrgDt.m_DepreciationRate;
            m_CapitalStock = csOrgDt.m_CapitalStock;
            m_Chash = csOrgDt.m_Chash;

            m_Debt = csOrgDt.m_Debt;
            m_DebtInterestRate = csOrgDt.m_DebtInterestRate;
            m_Credit = csOrgDt.m_Credit;
            m_CreditInterestRate = csOrgDt.m_CreditInterestRate;

            //m_Expense = csOrgDt.m_Expense;
            m_NonMaterial_Val = csOrgDt.m_NonMaterial_Val;
            m_DriftCost = csOrgDt.m_DriftCost;
            m_Benefit = csOrgDt.m_Benefit;

            Default_FLG = csOrgDt.Default_FLG;

            m_Materials = csOrgDt.m_Materials;
            m_MaterialsUnitCost = csOrgDt.m_MaterialsUnitCost;
            m_dProduct = csOrgDt.m_dProduct;
            m_dPrductUnitCost = csOrgDt.m_dPrductUnitCost;
            m_dFeedCapability = csOrgDt.m_dFeedCapability;
            m_dDealingChash = csOrgDt.m_dDealingChash;
            m_dNextDealingChash = csOrgDt.m_dNextDealingChash;
            m_dProductNextOrder = csOrgDt.m_dProductNextOrder;

            m_OrdersPlaced = csOrgDt.m_OrdersPlaced;
            m_EstimatedCost = csOrgDt.m_EstimatedCost;
            m_Payment = csOrgDt.m_Payment;
            m_Claimed = csOrgDt.m_Claimed;
            m_ContributionRatioForProduct = csOrgDt.m_ContributionRatioForProduct;

            m_HmnActTimeSpan = csOrgDt.m_HmnActTimeSpan;
            m_WorkTime = csOrgDt.m_WorkTime;
            m_HmnReqO2 = csOrgDt.m_HmnReqO2;
            m_HmnRcvO2 = csOrgDt.m_HmnRcvO2;
            m_HmnCO2Emission = csOrgDt.m_HmnCO2Emission;
            m_HmnCO2EmissionDay = csOrgDt.m_HmnCO2EmissionDay;

            return true;
        }

        public virtual void CalStart()
        {

        }

        /// <summary>
        /// 各種経費
        /// </summary>
        /// <param name="dActDay">動作日数</param>
        /// <param name="dDriftCost">変動経費</param>
        /// <returns></returns>
        public virtual void CalConstCost( double dActDay, double dDriftCost)
        {
            // 現伽償却
            //dCost += this.m_Facility * (this.m_DepreciationRate / 365.25) * dActDay;
            this.m_Facility = this.m_Facility * (1.0 - (this.m_DepreciationRate / 365.25) * dActDay);
  
            double dCost = 0.0;
            // 利子
            dCost += this.m_Debt * this.m_DebtInterestRate;
            this.m_Debt = this.m_Debt * (1.0 - (this.m_DebtInterestRate / 365.25) * dActDay);
            // 変動コスト反映
            m_DriftCost = dDriftCost;
            dCost += m_DriftCost;

            //m_Income -= dCost;
            m_Chash -= dCost;
        }
     

        //----------- McOceanBaseDefine.DEALING----McOceanBaseDefine.PRODUCT----------------
        public virtual void ProductBuyerReceive( double dProduct, double UnitCost, double dCapability)
        {
            // 製品積み上げ
            m_Materials += dProduct;
            m_MaterialsUnitCost = UnitCost;
            m_dFeedCapability = dCapability;

            // 発注分は入荷の為減らす
            m_dNextDealingChash -= dProduct * m_MaterialsUnitCost;
        }
        public virtual void ProductBuyerCalDealling(double dOrder)
        {
            m_dNextDealingChash += dOrder;
            m_dDealingChash = dOrder;
            if(m_Chash < m_dDealingChash)
            {
                m_dDealingChash = m_Chash;
            }
            m_Chash -= m_dDealingChash;
        }
        public virtual void ProductSellerReceive( double dCash, double dOrder )
        {
            //m_dDealingChash += dCash;
            m_Chash += dCash;
            m_dProductNextOrder += dOrder;

            //m_Income += dCash;
            //m_Chash += dCash;

        }
        public virtual void ProductSellerCalDealling(double dUsedMaterials)
        {
            m_Materials -= dUsedMaterials;
            if(m_Materials < 0) { m_Materials = 0; }

            m_dProduct = m_dProductNextOrder / (m_dPrductUnitCost +1E-16);
            if(m_dFeedCapability < m_dProduct)
            {
                m_dProduct = m_dFeedCapability;
            }

            m_dProductNextOrder -= m_dProduct * m_dPrductUnitCost;
            if(m_dProductNextOrder < 0) { m_dProductNextOrder = 0; }

            //m_Chash += m_dDealingChash;
            //m_dDealingChash = 0.0;
        }

        //---------McOceanBaseDefine.CHASH-----------------
        /// <summary>
        /// 買い手側：請求、コスト見積もり等受け取り
        /// </summary>
        /// <param name="dClaimed"></param>
        /// <param name="EstCost"></param>
        /// <param name="ContributeionRk"></param>
        public virtual void BuyerReceiveOutcom( double dClaimed, double EstCost, double ContributeionRk )
        {
            // 請求額
            m_Claimed += dClaimed;
            // 次回の見積もり
            m_EstimatedCost += EstCost;
            m_NonMaterial_Val += dClaimed * ContributeionRk;
        }
        /// <summary>
        /// 買い手　支払額計算、
        /// </summary>
        public virtual void BuyerCalClaimedPayment()
        {
            if (m_Chash > m_Claimed)
            {
                m_Payment = m_Claimed;
            }
            else
            {
                m_Payment = m_Chash;
            }
            m_OrdersPlaced = m_EstimatedCost;
            
            m_Claimed -= m_Payment;
            if(m_Claimed < 0) { m_Claimed = 0; }
            m_Chash -= m_Payment;
        }

        /// <summary>
        /// 売り手側の　次受注、及び、支払い受け取り
        /// </summary>
        /// <param name="dOrder"></param>
        /// <param name="dPayment"></param>
        public virtual void SellerReceivePayment( double dOrder, double dPayment)
        {
            m_OrdersPlaced += dOrder;
            m_Claimed += dOrder;

            m_Payment = dPayment;
            m_dNowUnitPlace = dPayment;
            //m_Income += dPayment;
            //m_Chash += dPayment;
        }
        /// <summary>
        /// 売り手側の　
        /// </summary>
        public virtual void SellerCalClaimedPayment()
        {
            // m_Payment: 受け取った対価

            // 請求額は、受け取った値分減らせる
            m_Claimed -= m_Payment;
            if(m_Claimed < 0) { m_Claimed = 0; }

            // 受注積み残し量は出荷量を引いた値になる
            m_OrdersPlaced -= m_Claimed;
            if(m_OrdersPlaced < 0) { m_OrdersPlaced = 0; }

            // 次回の見積額
            // m_EstimatedCost = 
            m_Chash += m_Payment;
            m_Payment = 0;

        }
    }

}
