// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2024 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.


using System;
using System.Collections.Generic;
using System.Linq;
using Hiperscan.AnalysisModule;
using Hiperscan.ApoIdentCore.Misc;
using Hiperscan.ApoIdentCore.Reporting.ReportData;
using Hiperscan.PdfLib;
using Hiperscan.Unix;

namespace Hiperscan.ApoIdentCore.Reporting.Protocol.SubstanceProperties
{
    public class CommonSubstanceProperties : IDraw
    {
        protected virtual void Init(PdfArgs args)
        {
            this.Args = args;
            this.DeadLineDate = this.Info.MinExpiryDate.ToString("d");
            this.ReferenceQuantity = this.Info.ReferenceQuantity;
            this.DeliveryDate = this.Info.DeliveryDate == I18nDateFormat.EmptyDate ? String.Empty : this.Info.DeliveryDate.ToString("d");
        }

        public bool Draw(PdfArgs args)
        {
            this.Init(args);

            this.Layout.Feed(this.Args.ReferenceParagraphFeed * 1.5);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.Args.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph(this.TestedSubstanceLabel) == false)
                return false;
            this.Layout.XPosition = this.Args.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.GetSelectSubstanceName()) == false)
                return false;

            if (this.Args.State.CurrentPage > 1)
            {
                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);
                return true;
            }

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.Args.ReferenceFontSize, PdfColors.Black);
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph(this.SynonymsLabel) == false)
                return false;
            this.Layout.XPosition = this.Args.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.GetSynonyms()) == false)
                return false;

            this.Layout.Feed(this.Args.ReferenceParagraphFeed * 1.5);
            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.Args.ReferenceFontSize, PdfColors.Black);

            double column3_width = this.MeasureColumnWidth(this.InitLabelColumn());
            double column4_width = this.MeasureColumnWidth(this.InitContentColumn());

            this.IndentX0 = 0;
            this.IndentX1 = this.Args.ReferenceTabIndent;
            this.IndentX2 = this.Layout.InnerPageWidth -column3_width - column4_width - 10;
            this.IndentX3 = this.Layout.InnerPageWidth - column4_width - 2;
            this.Column0Width = this.IndentX2 - this.Args.ReferenceTabIndent - 30;
                                                
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);

            this.DoLineFeed = false;

            if (this.DrawRow0Right() == false)
                return false;

            if (this.DrawRow0Left() == false)
                return false;

            if (this.DoLineFeed)
            {
                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);
                this.DoLineFeed = false;
            }

            if (this.DrawRow1Right() == false)
                return false;

            if (this.DrawRow1Left() == false)
                return false;

            if (this.DoLineFeed)
            {
                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);
                this.DoLineFeed = false;
            }

            if (this.DrawRow2Right() == false)
                return false;

            if (this.DrawRow2Left() == false)
                return false;

            if (this.DoLineFeed)
            {
                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);
                this.DoLineFeed = false;
            }

            if (this.DrawRow3Right() == false)
                return false;

            if (this.DrawRow3Left() == false)
                return false;

            if (this.DoLineFeed)
            {
                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);
                this.DoLineFeed = false;
            }

            if (this.DrawRow4Right() == false)
                return false;

            if (this.DrawRow4Left() == false)
                return false;

            if (this.DoLineFeed)
            {
                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);
                this.DoLineFeed = false;
            }

            if (this.DrawRow5Right() == false)
                return false;

            if (this.DrawRow5Left() == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.Args.ReferenceLineDistance);
            return true;
        }

        protected string GetSelectSubstanceName()
        {
            string name = this.Info.SelectedName;

            if (this.Info.AnalysisType == AnalysisType.Quantification)
            {
                name += "   ";
                name += this.VarietyLabel;
                name += " ";
                name += this.Info.Variety;
            }

            return name;
        }

        protected virtual bool DrawRow0Left()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX0;
            if (this.Layout.AddParagraph(this.BatchLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX1;
            return this.Layout.AddParagraph(this.Info.Batch, this.Column0Width);
        }

        protected virtual bool DrawRow0Right()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX2;
            if (this.Layout.AddParagraph(this.DeadLineLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX3;
            return this.Layout.AddParagraph(this.DeadLineDate);
        }

        protected virtual bool DrawRow1Left()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX0;
            if (this.Layout.AddParagraph(this.ProducerLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX1;  
            return this.Layout.AddParagraph(this.Info.Producer, this.Column0Width);
        }

        protected virtual bool DrawRow1Right()
        {
            return true;
        }

        protected virtual bool DrawRow2Left()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX0;
            if (this.Layout.AddParagraph(this.PPNLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX1;
            return this.Layout.AddParagraph(this.Info.Ppn, this.Column0Width);
        }

        protected virtual bool DrawRow2Right()
        {
            return true;
        }

        protected virtual bool DrawRow3Left()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX0;
            if (this.Layout.AddParagraph(this.CorrectionFactorLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX1;
            return this.Layout.AddParagraph(this.Info.CorrectionFactor, this.Column0Width);
        }

        protected virtual bool DrawRow3Right()
        {
            return true;
        }

        protected virtual bool DrawRow4Left()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX0;
            if (this.Layout.AddParagraph(this.DistributorLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX1;
            return this.Layout.AddParagraph(this.Info.Distributor, this.Column0Width);
        }

        protected virtual bool DrawRow4Right()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX2;
            if (this.Layout.AddParagraph(this.ReferenceQuantityLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX3;
            return this.Layout.AddParagraph(this.ReferenceQuantity);
        }

        protected virtual bool DrawRow5Left()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX0;
            if (this.Layout.AddParagraph(this.PriceLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX1;
            return this.Layout.AddParagraph(this.Info.Price, this.Column0Width);
        }

        protected virtual bool DrawRow5Right()
        {
            this.DoLineFeed = true;

            this.Layout.XPosition = this.IndentX2;
            if (this.Layout.AddParagraph(this.DeliveryDateLabel) == false)
                return false;

            this.Layout.XPosition = this.IndentX3;
            return this.Layout.AddParagraph(this.DeliveryDate);
        }


        protected string GetSynonyms()
        {
            return String.Join("; ", this.Info.Synonyms.ToArray());
        }

        protected double MeasureColumnWidth(List<string> values)
        {
            double width = 0;

            foreach (string value in values)
            {
                double tmp = this.Layout.MeasureString(value);
                if (tmp > width)
                    width = tmp;
            }

            return width;
        }

        protected virtual List<string> InitLabelColumn()
        {
            List<string> tmp = new List<string>();

            tmp.Add(this.DeadLineLabel);
            tmp.Add(this.ReferenceQuantityLabel);
            tmp.Add(this.DeliveryDateLabel);

            return tmp;
        }

        protected virtual List<string> InitContentColumn()
        {
            List<string> tmp = new List<string>();

            tmp.Add(this.DeadLineDate);
            tmp.Add(this.ReferenceQuantity);
            tmp.Add(this.DeliveryDate);

            return tmp;
        }

        protected Layout Layout
        {
            get
            {
                return this.Args.Layout;
            }
        }

        protected ReportInfo Info
        {
            get
            {
                return this.Args.Info;
            }
        }

        protected PdfArgs Args { get; set; }

        protected string TestedSubstanceLabel => Catalog.GetString("Tested substance:");
        protected string SynonymsLabel => Catalog.GetString("Synonyms:");
        protected string BatchLabel => Catalog.GetString("Batch:");
        protected string ProducerLabel => Catalog.GetString("Producer:");
        protected string PPNLabel => Catalog.GetString("PPN:");
        protected string CorrectionFactorLabel => Catalog.GetString("Correc. factor:");
        protected string DistributorLabel => Catalog.GetString("Supplier:");
        protected string PriceLabel => Catalog.GetString("Cost Price:");
        protected string VarietyLabel => Catalog.GetString("Variety:");

        protected string DeadLineLabel => Catalog.GetString("Expiry date:"); //Verwendbar bis:
        protected string ReferenceQuantityLabel => Catalog.GetString("Quantity:"); //Bezugsmenge:
        protected string DeliveryDateLabel => Catalog.GetString("Delivery date:"); //Lieferdatum:

        protected string DeadLineDate { get; set; }
        protected string ReferenceQuantity { get; set; }
        protected string DeliveryDate { get; set; }

        protected double IndentX0 { get; set; }
        protected double IndentX1 { get; set; }
        protected double IndentX2 { get; set; }
        protected double IndentX3 { get; set; }
        protected double Column0Width { get; set; }

        protected bool DoLineFeed { get; set; }
    }
}
