// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2018 Thomas Klose & Torsten Schache, 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.Globalization;
using System.IO;

using Hiperscan.Common.I18n;
using Hiperscan.PdfLib;
using Hiperscan.Spectroscopy;
using Hiperscan.Spectroscopy.IdentModule;


namespace Hiperscan.Extensions.ApoIdent.Report
{
    public  abstract partial class GermanTemplate : Generic
    {
        protected GermanTemplate(ReportInfo report_info) : base(report_info)
        {
        }

        protected override bool CreateAddressHeader()
        {
            this.Layout.Feed(30);

            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Text = String.Format("\nDatum: {0}\nPrüfnummer: {1}", 
                                      Locale.LocalizedDate(this.ReportInfo.Date, this.ReportInfo.Culture),
                                      this.ReportInfo.TestId);
         
            if (this.Layout.AddParagraph(this.Text, PdfTextAlignments.Right) == false)
                return false;

            this.Text = String.Format("{0}\n{1}, {2}\nPrüfende/r: {3}",
                                      this.ReportInfo.Company,
                                      this.ReportInfo.Street,
                                      this.ReportInfo.Town,
                                      this.ReportInfo.User);

            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

        protected override bool CreateSubstanceProperties()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed * 1.5);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Geprüfte Substanz:") == false)
                return false;
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.GetSubstanceName()) == false)
                return false;
            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            if (this.Layout.AddParagraph(this.GetLatinName()) == false)
                return false;

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

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Hersteller/Lieferant:") == false)
                return false;
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.ReportInfo.Supplier) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Charge:") == false)
                return false;

            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = this.ReportInfo.Batch;
            if (String.IsNullOrEmpty(this.ReportInfo.Pzn) == false)
                this.Text += " " + String.Format("(PZN: {0})", this.ReportInfo.Pzn);
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;
         
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph(this.ReportInfo.Label.UseByDate) == false)
                return false;
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(Locale.LocalizedUseByDate(this.ReportInfo.ExpireDate, this.ReportInfo.Culture)) == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Einwaagekorrekturfaktor:") == false)
                return false;
            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = this.ReportInfo.CorrectionFactor;
            if (String.IsNullOrWhiteSpace(this.Text))
                this.Text = "k.A.";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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


        protected override bool CreateNirProperties()
        {

            if (this.ReportInfo.IsMeasurable == false)
                return true;

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

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Prüfmethode:") == false)
                return true;
            this.Text = "NIR-Spektroskopie (Ph.Eur 10.0/2.2.40) ";
            if (this.ReportInfo.SpectrumType == SpectrumType.ProcessedFluidSpecimen)
            {
                this.Text += "mit Transflexionseinsatz";
            }
            else if (this.ReportInfo.SpectrumType == SpectrumType.ProcessedSolidSpecimen)
            {
                if (this.ReportInfo.ProbeType == ProbeType.FinderInsert ||
                    this.ReportInfo.ProbeType == ProbeType.FinderSDInsert)
                    this.Text += "mit Probeneinsatz";
                else
                    this.Text += "in diffuser Reflexion";
            }
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.Text) == false)
                return true;


            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Gerät:") == false)
                return true;
            Text = String.Format("Name: {0} / Seriennummer: {1}", this.ReportInfo.DeviceName, 
                                 this.ReportInfo.OemSerialNumber);            
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.Text) == false)
                return true;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Substanzklasse:") == false)
                return true;
            Text = String.Format("{0}", this.ReportInfo.SubstanceClass);
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.Text) == false)
                return true;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Modell:") == false)
                return true;

            this.Text = this.ReportInfo.Version;
            if (this.ReportInfo.AccessDatabaseType == AccessDatabaseType.Extension)
                this.Text += " (hinzugefügt)";
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.Text) == false)
                return true;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Proben-/Substanz-ID:") == false)
                return true;
            this.Text = this.ReportInfo.MatchId + "/" + this.ReportInfo.SelectedSubstanceId;
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.Text) == false)
                return true;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Protokolldatei:") == false)
                return false;
            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = Path.GetFileName(this.ReportInfo.PdfFileFullName);
            if (String.IsNullOrEmpty(this.Text) == true)
                this.Text = " ";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

        protected override bool CreateCommentProperties()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Bemerkung:") == false)
                return false;
            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph(this.ReportInfo.Comment) == false)
                return false;

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

        protected override bool CreateGraphics()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            if (this.ReportInfo.IsMeasurable == false)
            {
                if (this.Layout.AddHorizontalLine(0, this.Layout.YPosition, this.Layout.InnerPageWidth, 0.5f) == false)
                    return false;
            }
            else
            {
                this.Layout.Feed(5);

                double padding = 1;
                int bitmap_save_width = (int)this.Layout.InnerPageWidth;
                int bitmap_save_height = (int)(0.8 * bitmap_save_width);
                double reference_width = this.Layout.InnerPageWidth / 2 - 2 * padding;


                DetailsPlot plot = new DetailsPlot(this.ReportInfo, false);
                plot.Dispose();

                PdfPoint point1 = new PdfPoint(padding, this.Layout.YPosition);
                System.Drawing.Bitmap bmp1 = plot.Plot1.GetBitmap(bitmap_save_width, bitmap_save_height);
                if (this.Layout.AddBitmap(bmp1, point1, PdfBitmapScales.X, reference_width) == false)
                    return false;

                PdfPoint point2 = new PdfPoint(this.Layout.InnerPageWidth / 2 + padding, this.Layout.YPosition);
                System.Drawing.Bitmap bmp2 = plot.Plot2.GetBitmap(bitmap_save_width, bitmap_save_height);
                if (this.Layout.AddBitmap(bmp2, point2, PdfBitmapScales.X, reference_width) == false)
                    return false;

                this.Layout.Feed(5 + this.Layout.ImageBoundingBox.Height);
            }
            return true;
        }

        protected override bool CreateNirResultSection()
        {
            if (this.ReportInfo.IsMeasurable == false)
                return true;

            bool success = true;

            if (this.ReportInfo.IsMatch == false)
            {
                switch (this.ReportInfo.ClassificationType)
                {
                    case ClassificationType.Single:
                        if (this.CreateSingleNegativeResult() == false)
                            success = false;
                        break;

                    case ClassificationType.Multiple:
                        if (this.CreateMultipleNegativeResult() == false)
                            success = false;
                        break;

                    case ClassificationType.NonMultiple:
                        if (this.CreateNonMultipleNegativeResult() == false)
                            success = false;
                        break;

                    default:
                        break;

                }
            }
            else
            {
                switch (this.ReportInfo.ClassificationType)
                {
                    case ClassificationType.Single:
                        if (this.CreateSinglePositiveResult() == false)
                            success = false;
                        break;

                    case ClassificationType.Multiple:
                        if (this.CreateMultiplePositiveResult() == false)
                            success = false;
                        break;

                    case ClassificationType.NonMultiple:
                        if (this.CreateNonMultiplePositiveResult() == false)
                            success = false;
                        break;

                    default:
                        break;

                }
            }

            return success;
        }

        protected override bool CreateSingleNegativeResult()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Ergebnis NIR:") == false)
                return false;

            double nir_width = this.Layout.MeasureString("Ergebnis NIR:");
            this.Layout.XPosition = nir_width + 10;
            this.Text = "negativ";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            double identified_width = this.Layout.MeasureString(this.Text);
            if (this.Layout.AddHorizontalLine(this.Layout.XPosition, this.Layout.YPosition +
                this.Layout.ParagraphBoundingBox.Height + 2, identified_width, 0.5) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = "Die Probe wurde nicht identifiziert als:";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);
            if (this.Layout.AddParagraph(this.GetSubstanceName()) == false)
                return false;

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

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);

            return true;
        }

        protected override bool CreateSinglePositiveResult()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Ergebnis NIR:") == false)
                return false;

            double nir_width = this.Layout.MeasureString("Ergebnis NIR:");

            this.Layout.XPosition = nir_width + 10;
            this.Text = "OK";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            double identified_width = this.Layout.MeasureString(this.Text);
            if (this.Layout.AddHorizontalLine(this.Layout.XPosition, this.Layout.YPosition +
                this.Layout.ParagraphBoundingBox.Height + 2, identified_width, 0.5) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = "Die Probe wurde identifiziert als:";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);
            if (this.Layout.AddParagraph(this.GetSubstanceName()) == false)
                return false;

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

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

        protected override bool CreateMultipleNegativeResult()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Ergebnis NIR:") == false)
                return false;

            double nir_width = this.Layout.MeasureString("Ergebnis NIR:");
            this.Layout.XPosition = nir_width + 10;
            this.Text = "negativ";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            double identified_width = this.Layout.MeasureString(this.Text);
            if (this.Layout.AddHorizontalLine(this.Layout.XPosition, this.Layout.YPosition +
                this.Layout.ParagraphBoundingBox.Height + 2, identified_width, 0.5) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = "Die Probe wurde nicht identifiziert als:";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);
            if (this.Layout.AddParagraph(this.GetSubstanceName()) == false)
                return false;

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

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

        protected override bool CreateMultiplePositiveResult()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Ergebnis NIR:") == false)
                return false;

            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = String.Format("Die Probe wurde als eine Substanz der Gruppe {0}* identifiziert.",
                                      this.ReportInfo.ClassificationName);
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);
            this.Text = "Alle anderen Substanzen der Datenbank konnten anhand des NIR-Spektrums " +
                "ausgeschlossen werden. Erst eine zusätzliche Prüfung, welche innerhalb " +
                "dieser Gruppe unterscheidet, macht das Prüfergebnis eindeutig.";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA_OBLIQUE, this.ReferenceFontSize, PdfColors.Black);
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);
            if (this.Layout.AddParagraph("*") == false)
                return false;

            double asterisk_width = Layout.MeasureString("*") * 2;
            this.Layout.XPosition = this.ReferenceTabIndent + asterisk_width;
            this.Text = String.Join("; ", this.ReportInfo.SubstanceNamesOfClassification.ToArray());
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

        protected override bool CreateNonMultipleNegativeResult()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Ergebnis NIR:") == false)
                return false;

            double nir_width = this.Layout.MeasureString("Ergebnis NIR:");
            this.Layout.XPosition = nir_width + 10;
            this.Text = "negativ";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            double identified_width = this.Layout.MeasureString(this.Text);
            if (this.Layout.AddHorizontalLine(this.Layout.XPosition, this.Layout.YPosition +
                this.Layout.ParagraphBoundingBox.Height + 2, identified_width, 0.5) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = String.Format("Die Probe wurde nicht als eine Charge der Substanz {0}* identifiziert.",
                                      this.ReportInfo.ClassificationName);
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

            this.Layout.SetFont(PdfFontTypes.HELVETICA_OBLIQUE, this.ReferenceFontSize, PdfColors.Black);
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);
            if (this.Layout.AddParagraph("*") == false)
                return false;

            double asterisk_width = Layout.MeasureString("*") * 2;
            this.Layout.XPosition = this.ReferenceTabIndent + asterisk_width;
            this.Text = String.Format("Folgende Chargen der Substanz sind in der Datenbank erfasst: {0}",
                                      String.Join("; ", this.ReportInfo.BatchNumbers.ToArray()));
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

        protected override bool CreateNonMultiplePositiveResult()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Ergebnis NIR:") == false)
                return false;

            double nir_width = this.Layout.MeasureString("Ergebnis NIR:");

            this.Layout.XPosition = nir_width + 10;
            this.Text = "OK";
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            double identified_width = this.Layout.MeasureString(this.Text);
            if (this.Layout.AddHorizontalLine(this.Layout.XPosition, this.Layout.YPosition +
                this.Layout.ParagraphBoundingBox.Height + 2, identified_width, 0.5) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = String.Format("Die Probe wurde als eine Charge der Substanz {0}* identifiziert.",
                                      this.ReportInfo.ClassificationName);
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

            this.Layout.SetFont(PdfFontTypes.HELVETICA_OBLIQUE, this.ReferenceFontSize, PdfColors.Black);
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);
            if (this.Layout.AddParagraph("*") == false)
                return false;

            double asterisk_width = Layout.MeasureString("*") * 2;
            this.Layout.XPosition = this.ReferenceTabIndent + asterisk_width;
            this.Text = String.Format("Folgende Chargen sind für die Substanz in der Datenbank erfasst: {0}",
                                      String.Join("; ", this.ReportInfo.BatchNumbers.ToArray()));
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

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

        protected override bool AddNirEvaluation()
        {
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height);
            this.Layout.Feed(0.6 * this.ReferenceParagraphFeed);

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);
            string min_rating = (this.ReportInfo.MinRating * 100).ToString("f1", this.Culture);
            string rating = (this.ReportInfo.Rating * 100).ToString("f1", this.Culture);
            if (this.ReportInfo.IsMatch == false && min_rating == rating)
                rating = (this.ReportInfo.MinRating * 100 - 0.1).ToString("f1", this.Culture);
            this.Text = String.Format("Bewertung: {0}% (Sollwert {1}% bis 100%)", rating, min_rating);
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            if (this.ReportInfo.HasValidationDocument == true)
            {
                if (this.ReportInfo.ClassificationType == ClassificationType.NonMultiple ||
                    ApoIdentEnvs.DebugOn)
                {
                    string result = this.ReportInfo.SignificanceLevel;
                    if (String.IsNullOrEmpty(result) == false)
                    {
                        this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);

                        string[] values = result.Split(new char[] { ' ' });
                        if (this.ReportInfo.IsMatch == true)
                            this.Text = String.Format("{0} Spezifität ({1} statistische Prognose)", values[0], values[1]);
                        else
                            this.Text = String.Format("{0} Erkennungsrate ({1} statistische Prognose)", values[0], values[1]);

                        if (this.Layout.AddParagraph(this.Text) == false)
                            return false;
                    }
                }
            }

            return true;
        }

        protected override bool CreateAdditionalTest()
        {
            this.Layout.Feed(this.ReferenceParagraphFeed * 1.5);
            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);

            double y_pos = this.Layout.YPosition;
            double next_feed = 0;
            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph(this.SubstanceTestType) == false)
                return false;

            if (this.State.CurrentPage == 1 && this.State.IsSet(PdfCreationStates.CreateTwoSides) == true)
            {
                this.Layout.XPosition = this.ReferenceTabIndent;
                if (this.Layout.AddParagraph("Siehe Seite 2") == false)
                    return false;

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

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            if (this.Layout.AddParagraph("(Methode und Ergebnisse)") == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            next_feed = this.Layout.YPosition;

            this.Layout.YPosition = y_pos;

            this.Layout.XPosition = this.ReferenceTabIndent;



            if (String.IsNullOrEmpty(this.ReportInfo.AdditionalTest) == false)
            {
                if (this.Layout.AddParagraph(this.ReportInfo.AdditionalTest) == false)
                    return false;

                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            }
            else
            {
                double width = this.Layout.InnerPageWidth - this.Layout.XPosition;

                for (int i = 0; i < this.NumberOfAdditionalTextLines; i++)
                {
                    this.Layout.Feed(1.5 * Generic.DEFAULT_FEED);
                    if (this.Layout.AddHorizontalLine(this.Layout.XPosition, this.Layout.YPosition, width, 0.5) == false)
                        return false;
                }
            }

            if (this.Layout.YPosition < next_feed)
                this.Layout.YPosition = next_feed;
            return true;
        }

        protected override bool CreateFinalResult()
        {
            if (this.State.CurrentPage == 1 && this.State.IsSet(PdfCreationStates.CreateTwoSides) == true)
                return true;
            
            if (this.ReportInfo.ClassificationType != ClassificationType.Multiple &&
                this.ReportInfo.IsMeasurable == true &&
                this.ReportInfo.IsMatch == true)
                return true;

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

            this.Layout.XPosition = 0;
            if (this.Layout.AddParagraph("Abschlussergebnis:") == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);
            this.Layout.XPosition = this.ReferenceTabIndent;
            this.Text = String.Format("{0} wurde eindeutig identifiziert.", this.GetSubstanceName());
            if (this.Layout.AddParagraph(this.Text) == false)
                return false;

            if (this.ReportInfo.CustomerResult == false)
            {
                this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height * 1.6);

                PdfRect sqaure_yes = new PdfRect(this.ReferenceTabIndent, this.Layout.YPosition,
                    this.ReferenceFontSize, this.ReferenceFontSize);
                if (this.Layout.AddRectangle(sqaure_yes, 0.5, PdfColors.Black) == false)
                    return false;

                this.Layout.YPosition -= 0.15 * this.ReferenceFontSize;
                this.Layout.XPosition = this.ReferenceTabIndent + this.ReferenceFontSize * 1.2;
                if (this.Layout.AddParagraph("Ja") == false)
                    return false;
                this.Layout.YPosition += 0.15 * this.ReferenceFontSize;

                double no_indent = 50;
                PdfRect sqaure_no = new PdfRect(this.ReferenceTabIndent + no_indent, this.Layout.YPosition,
                    this.ReferenceFontSize, this.ReferenceFontSize);
                if (this.Layout.AddRectangle(sqaure_no, 0.5, PdfColors.Black) == false)
                    return false;

                this.Layout.YPosition -= 0.15 * this.ReferenceFontSize;
                this.Layout.XPosition = this.ReferenceTabIndent + no_indent + this.ReferenceFontSize * 1.2;
                if (this.Layout.AddParagraph("Nein") == false)
                    return false;
                this.Layout.YPosition += 0.15 * this.ReferenceFontSize;
            }

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

        protected override bool CreateTestCertificateSection()
        {
            if (this.ReportInfo.ProtocolType != ProtocolType.ApoIdent && Locale.Language == "de")
                return true;

            if (this.State.CurrentPage == 1 && this.State.IsSet(PdfCreationStates.CreateTwoSides) == true)
                return true;

            this.Layout.Feed(this.ReferenceParagraphFeed * 1.1);
            this.Layout.SetFont(PdfFontTypes.HELVETICA_OBLIQUE, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph("> Prüfzertifikat hier oder auf der Folgeseite einkleben <") == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + 20 * Generic.DEFAULT_LINE_DISTANCE);
            return true;
        }

        protected override bool CreateSignature()
        {
            if (this.ReportInfo.ProtocolType != ProtocolType.ApoIdent && Locale.Language == "de")
                return true;

            this.Layout.Feed(50);
            this.Layout.SetFont(PdfFontTypes.HELVETICA, this.ReferenceFontSize, PdfColors.Black);

            this.Layout.XPosition = this.ReferenceTabIndent;
            if (this.Layout.AddParagraph("Freigabe durch Apotheker/in:") == false)
                return false;

            this.Layout.Feed(this.ReferenceFontSize);
            this.Layout.XPosition = 300;
            if (this.Layout.AddHorizontalLine(this.Layout.XPosition, this.Layout.YPosition, 150, 0.5) == false)
                return false;

            this.Layout.SetFont(PdfFontTypes.HELVETICA, 0.8 * this.ReferenceFontSize, PdfColors.Black);
            if (this.Layout.AddParagraph("Unterschrift", 150, PdfTextAlignments.Center) == false)
                return false;

            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + this.ReferenceLineDistance);
            return true;
        }
      
        protected override void CreateFooter()
        {
            this.Layout.SetFont(PdfFontTypes.HELVETICA_BOLD, 5, PdfColors.Black);

            this.Layout.YPosition = this.Layout.InnerPageHeight + 10;
            this.Layout.XPosition = 0;

            this.Text = String.Format("Seite {0}", this.State.CurrentPage);
            this.Layout.AddFooter(this.Text, PdfTextAlignments.Right);

            this.Layout.SetFont(PdfFontTypes.HELVETICA, 5, PdfColors.Black);
            this.Layout.Feed(this.Layout.ParagraphBoundingBox.Height + 2);

            this.Layout.XPosition = 0;
            this.Text = String.Format("{0}\n{1}",
                                      PdfFooter.Copyright,
                                      "www.apo-ident.de");
            this.Layout.AddFooter(this.Text);

            this.Layout.XPosition = 120;
            this.Text = String.Format("QuickStep Apo-Ident {0}", Plugin.version);
            if (this.ReportInfo.IsMeasurable == false)
            {
                this.Layout.AddFooter(this.Text);
                return;
            }

            this.Text += String.Format("\n{0} {1}",
                                       "Ident-Modul",
                                       IdentServerClient.Info?.Version.IdentModuleVersion ?? String.Empty);
            this.Layout.AddFooter(this.Text);

            this.Layout.XPosition = 240;
            this.Text = String.Format("SGS: {0}\n{1}: {2}, PCA: {3}",
                                      this.ReportInfo.Serial,
                                      "Weißreferenz",
                                      this.ReportInfo.WhiteReference,
                                      this.ReportInfo.PCAVersion);

            this.Layout.AddFooter(this.Text);
        }

        protected override string SubstanceTestType
        {
            get
            {
                string test_type = String.Empty;

                if (this.ReportInfo.IsMeasurable == true)
                {
                    if (this.ReportInfo.IsMatch == true)
                    {
                        if (this.ReportInfo.ClassificationType == ClassificationType.Multiple)
                            test_type = "Ergänzende Prüfung:";
                        else
                            test_type = "Zusätzliche Prüfung:";
                    }
                    else
                    {
                        test_type = "Identitätsprüfung:";
                    }
                }
                else
                {
                    test_type = "Identitätsprüfung:";
                }

                return test_type;
            }
        }

        protected override CultureInfo Culture { get; set; } = new CultureInfo("de-DE");
    }
}
