// Created with MonoDevelop
//
//    Copyright (C) 2017 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.Reflection;
using System.Collections.Generic; 
using System.Drawing;
using System.IO;

using Hiperscan.PdfLib;
using Hiperscan.Unix;


namespace Hiperscan.Pdf.SubstanceOverview
{
	
	public static class GranulatePdfCreator
	{
		public static void Create (List<GranulateEntry> list, string file_name, OverviewErrorType error_type, bool is_latin_sorted)
		{
			GranulatePdfCreator.Document = new Layout(PdfPageSizes.A4_PORTRAIT, file_name);
			GranulatePdfCreator.Document.PDF.SetTitle(Catalog.GetString("Overview for TCM"));
			GranulatePdfCreator.Document.PDF.SetSubject(Catalog.GetString("This document contains a list with TCM substances."));


			GranulatePdfCreator.IsLatinSorted = is_latin_sorted;
			GranulatePdfCreator.Document.LowerMargin = 50;
			
			Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("SubstanceOverview.Resources.Apo_Ident_Logo.png");
			GranulatePdfCreator.HiperscanLogo = new Bitmap(s);

			if (list == null || list.Count == 0)
			{
				if (error_type != OverviewErrorType.None)
					GranulatePdfCreator.CreateSorryPage(error_type);
			}
			else
			{
				GranulatePdfCreator.Version = String.Format(Catalog.GetString("Version from {0}"), DateTime.Now.ToString("dd.MM.yyyy"));
				GranulatePdfCreator.SubstancesTable = list;		


				
				GranulatePdfCreator.Document.SimulateDrawing = true;
				{
					GranulatePdfCreator.CurrentPageNumber = 1;
					GranulatePdfCreator.CreateContents();
					GranulatePdfCreator.TotalPageNumber = GranulatePdfCreator.CurrentPageNumber;
				}
			
				GranulatePdfCreator.Document.SimulateDrawing = false;
				{
					GranulatePdfCreator.CurrentPageNumber = 1;
					GranulatePdfCreator.CreateContents();
				}
			
			}
			//GranulatePdfCreator.CreatePageNumbers();
			//GranulatePdfCreator.CreateChapterNumbers();
			
			GranulatePdfCreator.Document.Save();
		}
		
		private static int CurrentPageNumber  		{get; set;}
		private static int TotalPageNumber  		{get; set;}
		
		private static Layout Document 				{get; set;}
		private static string Version				{get; set;}
		private static Bitmap HiperscanLogo 		{get; set;}
		
		private static List<GranulateEntry> SubstancesTable		{get; set;}
		private static bool IsLatinSorted 						{get; set;}
		
		
		
		
		
		#region table pages
		
		private static double VersionWidth 							{get;set;}
		
		//private static List<OverviewEntry> CurrentSubstanceNames 	{get;set;}
		private static int TableHeaderColor 						{get;set;}
		private static int TableRowColor							{get;set;}
		private static int TableLineColor 							{get;set;}
	
		private static double DefaultNamesEntryColumnWidth 			{get;set;}	
		private static double LatinNamesEntryColumnWidth 			{get;set;}
		private static double MeasurableColumnWidth					{get;set;}
		private static double CellSpace								{get;set;}
		private static double LineWidth								{get;set;}
		
		
		private static double MeasureNamesColumn(bool is_latin)
		{
			double max_width = Double.MinValue;
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA, 8, PdfColors.Black);
			foreach (GranulateEntry granulate_entry in GranulatePdfCreator.SubstancesTable)
			{
				string name = is_latin == false ? granulate_entry.DefaultNames[0] : granulate_entry.LatinNames[0];
				double width = GranulatePdfCreator.Document.MeasureString(name);
				if (width > max_width)
					max_width = width;
			}
			return max_width;
		}
		
		private static void CreateContents()
		{
			GranulatePdfCreator.TableHeaderColor 	= 0x00B33333;
			GranulatePdfCreator.TableRowColor 		= 0x00FFCCCC;
			GranulatePdfCreator.TableLineColor 		= 0X00E68080;
			

			GranulatePdfCreator.LineWidth = 1;
			GranulatePdfCreator.CellSpace = GranulatePdfCreator.LineWidth * 3;
			
			GranulatePdfCreator.DefaultNamesEntryColumnWidth 	= GranulatePdfCreator.MeasureNamesColumn(false);
			GranulatePdfCreator.DefaultNamesEntryColumnWidth += 2 * (GranulatePdfCreator.CellSpace);
			GranulatePdfCreator.LatinNamesEntryColumnWidth		= GranulatePdfCreator.MeasureNamesColumn(true);
			GranulatePdfCreator.LatinNamesEntryColumnWidth 	 += 2 * (GranulatePdfCreator.CellSpace);
			
			double free_space = (GranulatePdfCreator.DefaultNamesEntryColumnWidth + GranulatePdfCreator.LatinNamesEntryColumnWidth + 
				GranulatePdfCreator.LineWidth);
			free_space = GranulatePdfCreator.Document.InnerPageWidth - free_space;
			
			GranulatePdfCreator.MeasurableColumnWidth = free_space / 3;

			int start_index = 0;
			for(;;)
			{
				start_index = GranulatePdfCreator.CreateOnePageForEnumerations(start_index);
				if (start_index == -1)
					break;
				
				GranulatePdfCreator.Document.AddNewPage();
				GranulatePdfCreator.CurrentPageNumber++;
			}	
		}


		private static int CreateOnePageForEnumerations(int start_index)
		{
			PdfRect rect;
			string text;
			int row = 1;
			double top;
			double next_column;
			double height = 13;

			GranulatePdfCreator.Document.AddHeaderBitmap(GranulatePdfCreator.HiperscanLogo, new PdfPoint(GranulatePdfCreator.Document.InnerPageWidth - 105, -5), PdfBitmapScales.X, 105);
			
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA_BOLD, 10, PdfColors.Black);
			GranulatePdfCreator.Document.YPosition = 0;
			GranulatePdfCreator.Document.XPosition = 0;
			GranulatePdfCreator.Document.AddHeader(Catalog.GetString("List of Available TCM-Granulate per manufacturer / Supplier"));
			
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA_BOLD, 7, PdfColors.Black);
			GranulatePdfCreator.Document.YPosition = 12;
			GranulatePdfCreator.Document.XPosition = 0;
			
			if (GranulatePdfCreator.IsLatinSorted == false)
				GranulatePdfCreator.Document.AddHeader(Catalog.GetString("(sorted by Pin Yin names)"));
			else
				GranulatePdfCreator.Document.AddHeader(Catalog.GetString("(sorted by latin names)"));
			
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA, 8, PdfColors.Black);
			GranulatePdfCreator.Document.XPosition = 0;
			GranulatePdfCreator.Document.YPosition = GranulatePdfCreator.Document.InnerPageHeight + 20;
			GranulatePdfCreator.Document.AddFooter(GranulatePdfCreator.Version);
			
			//page entry
			if (GranulatePdfCreator.Document.SimulateDrawing == false)
			{
				GranulatePdfCreator.Document.XPosition = 0;
				GranulatePdfCreator.Document.YPosition = GranulatePdfCreator.Document.InnerPageHeight + 20;
				string page_number = String.Format(Catalog.GetString("Page {0} of {1}"), GranulatePdfCreator.CurrentPageNumber, GranulatePdfCreator.TotalPageNumber);
				GranulatePdfCreator.Document.AddFooter(page_number, PdfTextAlignments.Right);
			}
			
			
			
			
			top = 40;
			next_column = 0;
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA_BOLD, 8, PdfColors.White);
			
			//German column
			rect = new PdfRect(next_column, top, GranulatePdfCreator.DefaultNamesEntryColumnWidth, height);
			GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, 
			                                         GranulatePdfCreator.TableLineColor, GranulatePdfCreator.TableHeaderColor);
			text = Catalog.GetString("Pin Yin");
			GranulatePdfCreator.Document.YPosition = top + 1;
			GranulatePdfCreator.Document.XPosition = 0;
			GranulatePdfCreator.Document.AddParagraph(text, rect.Width, PdfTextAlignments.Center);	
			next_column += GranulatePdfCreator.DefaultNamesEntryColumnWidth - GranulatePdfCreator.LineWidth;
			
			//Latin Column
			rect = new PdfRect(next_column, top, GranulatePdfCreator.LatinNamesEntryColumnWidth, height);
			GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, 
			                                         GranulatePdfCreator.TableLineColor, GranulatePdfCreator.TableHeaderColor);
			GranulatePdfCreator.Document.XPosition = rect.X;
			GranulatePdfCreator.Document.YPosition = top + 1;
			GranulatePdfCreator.Document.AddParagraph(Catalog.GetString("Latin name"), rect.Width, PdfTextAlignments.Center);
			next_column += GranulatePdfCreator.LatinNamesEntryColumnWidth - GranulatePdfCreator.LineWidth;
			
			//china Column
			rect = new PdfRect(next_column, top, GranulatePdfCreator.MeasurableColumnWidth, height);
			GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, 
				                                         GranulatePdfCreator.TableLineColor, GranulatePdfCreator.TableHeaderColor);
			GranulatePdfCreator.Document.XPosition = rect.X;
			GranulatePdfCreator.Document.YPosition = top + 1;
			GranulatePdfCreator.Document.AddParagraph(Catalog.GetString("China Medica"), rect.Width, PdfTextAlignments.Center);
			next_column += GranulatePdfCreator.MeasurableColumnWidth - GranulatePdfCreator.LineWidth;
			
			//herba Column
			rect = new PdfRect(next_column, top, GranulatePdfCreator.MeasurableColumnWidth, height);
			GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, 
				                                         GranulatePdfCreator.TableLineColor, GranulatePdfCreator.TableHeaderColor);
			GranulatePdfCreator.Document.XPosition = rect.X;
			GranulatePdfCreator.Document.YPosition = top + 1;
			GranulatePdfCreator.Document.AddParagraph(Catalog.GetString("Herba Sinica"), rect.Width, PdfTextAlignments.Center);
			next_column += GranulatePdfCreator.MeasurableColumnWidth - GranulatePdfCreator.LineWidth;
			
			//phyte Column
			rect = new PdfRect(next_column, top, GranulatePdfCreator.MeasurableColumnWidth, height);
			GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, 
				                                         GranulatePdfCreator.TableLineColor, GranulatePdfCreator.TableHeaderColor);
			GranulatePdfCreator.Document.XPosition = rect.X;
			GranulatePdfCreator.Document.YPosition = top + 1;
			GranulatePdfCreator.Document.AddParagraph(Catalog.GetString("Phytocomm"), rect.Width, PdfTextAlignments.Center);
			next_column += GranulatePdfCreator.MeasurableColumnWidth - GranulatePdfCreator.LineWidth;

			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA, 8, PdfColors.Black);
			
			for(int i = start_index; i < GranulatePdfCreator.SubstancesTable.Count; i++)
			{
				string default_entry   	= GranulatePdfCreator.SubstancesTable[i].DefaultNames[0];
				string latin_entry 		= GranulatePdfCreator.SubstancesTable[i].LatinNames[0];
				string china_entry  	= GranulatePdfCreator.SubstancesTable[i].ChinaMedica == true ? "x" : String.Empty;
				string herba_netry  	= GranulatePdfCreator.SubstancesTable[i].HerbaSinica == true ? "x" : String.Empty;
				string phyto_entry  	= GranulatePdfCreator.SubstancesTable[i].PhytoComm == true ? "x" : String.Empty;
				
				int color = row % 2 == 1 ? GranulatePdfCreator.TableRowColor : PdfColors.White;
				
				top += height - 1;
				next_column = 0;
	
				
				
				//create default column
				rect = new PdfRect(next_column, top, GranulatePdfCreator.DefaultNamesEntryColumnWidth, height);
				if (GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, GranulatePdfCreator.TableLineColor, color) == false)
					return i;				
				GranulatePdfCreator.Document.XPosition = next_column + GranulatePdfCreator.CellSpace;
				GranulatePdfCreator.Document.YPosition = top + 1;
				GranulatePdfCreator.Document.AddParagraph(default_entry);
				next_column += GranulatePdfCreator.DefaultNamesEntryColumnWidth - GranulatePdfCreator.LineWidth;
				
				//latin column
				rect = new PdfRect(next_column, top, GranulatePdfCreator.LatinNamesEntryColumnWidth, height);	
				GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, GranulatePdfCreator.TableLineColor, color);
				GranulatePdfCreator.Document.XPosition = next_column + GranulatePdfCreator.CellSpace;
				GranulatePdfCreator.Document.YPosition = top + 1;
				GranulatePdfCreator.Document.AddParagraph(latin_entry);
				next_column += GranulatePdfCreator.LatinNamesEntryColumnWidth - GranulatePdfCreator.LineWidth;
				
				//china_entry column
				rect = new PdfRect(next_column, top, GranulatePdfCreator.MeasurableColumnWidth, height);
				GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, GranulatePdfCreator.TableLineColor, color);
				GranulatePdfCreator.Document.XPosition = next_column;
				GranulatePdfCreator.Document.YPosition = top + 1;
				GranulatePdfCreator.Document.AddParagraph(china_entry, GranulatePdfCreator.MeasurableColumnWidth, PdfTextAlignments.Center);
				next_column += GranulatePdfCreator.MeasurableColumnWidth - GranulatePdfCreator.LineWidth;
				
				//herba_entry column
				rect = new PdfRect(next_column, top, GranulatePdfCreator.MeasurableColumnWidth, height);
				GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, GranulatePdfCreator.TableLineColor, color);
				GranulatePdfCreator.Document.XPosition = next_column;
				GranulatePdfCreator.Document.YPosition = top + 1;
				GranulatePdfCreator.Document.AddParagraph(herba_netry, GranulatePdfCreator.MeasurableColumnWidth, PdfTextAlignments.Center);
				next_column += GranulatePdfCreator.MeasurableColumnWidth - GranulatePdfCreator.LineWidth;
				
				//herba_phyto column
				rect = new PdfRect(next_column, top, GranulatePdfCreator.MeasurableColumnWidth, height);
				GranulatePdfCreator.Document.AddRectangle(rect, GranulatePdfCreator.LineWidth, GranulatePdfCreator.TableLineColor, color);
				GranulatePdfCreator.Document.XPosition = next_column;
				GranulatePdfCreator.Document.YPosition = top + 1;
				GranulatePdfCreator.Document.AddParagraph(phyto_entry, GranulatePdfCreator.MeasurableColumnWidth, PdfTextAlignments.Center);

				row++;
			}
			
			return -1;
		}
		#endregion table pages

		#region sorry page
		private static void CreateSorryPage(OverviewErrorType error_type)
		{
			string text = String.Empty;

			//Create firm address
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA_BOLD, 10, PdfColors.Black);
			GranulatePdfCreator.Document.YPosition = 55;
			GranulatePdfCreator.Document.XPosition = 0;
			GranulatePdfCreator.Document.AddHeader("HiperScan GmbH");
			
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA, 9, PdfColors.Black);
			GranulatePdfCreator.Document.YPosition = 66;
			GranulatePdfCreator.Document.XPosition = 0;
			GranulatePdfCreator.Document.AddHeader("Weißeritzstr. 3, 01067 Dresden\nTel. 0351-212 496 0");
			

			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA_BOLD, 20, PdfColors.Black);
			switch (error_type)
			{
			case OverviewErrorType.NoAvailablePdf:
				text = Catalog.GetString("List of available substances cannot be shown.");
				break;
				
			case OverviewErrorType.NoNewPdf:
				text = Catalog.GetString("List of added substances cannot be shown.");
				break;
				
			case OverviewErrorType.NotMeasurablePdf:
				text = Catalog.GetString("List of not measurable substances cannot be shown.");
				break;

			default:
				break;
			}
				
			GranulatePdfCreator.Document.YPosition = 150;
			GranulatePdfCreator.Document.AddParagraph(text, PdfTextAlignments.Center);
			
			GranulatePdfCreator.Document.AddBitmap(GranulatePdfCreator.HiperscanLogo, new PdfPoint(GranulatePdfCreator.Document.InnerPageWidth - 105, 55), PdfBitmapScales.X, 105);
			
			Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("SubstanceOverview.Resources.sorry.bmp");
			Bitmap bitmap = new Bitmap(s);
			GranulatePdfCreator.Document.AddBitmap(bitmap, new PdfPoint(0.3 * GranulatePdfCreator.Document.InnerPageWidth, 
			                                                        0.4 * GranulatePdfCreator.Document.InnerPageHeight),
			                        PdfBitmapScales.X, 
			                                      0.3 * GranulatePdfCreator.Document.InnerPageWidth);
			
			
			GranulatePdfCreator.Document.SetFont(PdfFontTypes.HELVETICA, 12, PdfColors.Black);
			GranulatePdfCreator.Document.YPosition = 0.875 * GranulatePdfCreator.Document.InnerPageHeight;
			GranulatePdfCreator.Document.XPosition = 150;
			text = Catalog.GetString("Possible reasons for this error are:");
			GranulatePdfCreator.Document.AddParagraph(text);
			
			GranulatePdfCreator.Document.XPosition = 170;
			GranulatePdfCreator.Document.YPosition += 16;

			switch (error_type)
			{
			case OverviewErrorType.NoAvailablePdf:
				text = Catalog.GetString("- No substance groups are defined for this device.");
				GranulatePdfCreator.Document.AddParagraph(text);
				break;
				
			case OverviewErrorType.NoNewPdf:
				text = Catalog.GetString("- No substances have been added since last Ident Module update.");
				GranulatePdfCreator.Document.AddParagraph(text);
				break;
				
			case OverviewErrorType.NotMeasurablePdf:
				text = Catalog.GetString("- There aren't any not measurable substances.");
				GranulatePdfCreator.Document.AddParagraph(text);
				break;
			}

		}
		#endregion sorry page
	}
}