// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2017 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.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using System.Drawing.Printing;
using System.Text.RegularExpressions;

using Hiperscan.GtkExtensions.Compiler;
using Hiperscan.GtkExtensions.Printing;
using Hiperscan.Unix;
using System.Globalization;

namespace Hiperscan.Extensions.ApoIdent
{
	public class LabelPrinter
	{	
        public static readonly string USER_DEFINED_SIZE_NAME = Catalog.GetString("User defined");
        public const double USER_DEFINED_DEFAULT_WIDTH = 50;
        public const double USER_DEFINED_DEFAULT_HEIGHT = 30;

		public LabelPrinter(LabelPrinterSettings settings)
		{
			this.Settings = settings;
		}

		public void PrintTestLabel(Profile profile)
		{
			ReportInfo info = new ReportInfo();

			ReportCountryType report_country = ReportCountryType.Germany;
			if (profile != null)
				report_country = profile.ReportCountry;

			info.Culture = info.GetCulture(report_country);
         
			info.Company     = Catalog.GetString("Company name");
			info.Street      = Catalog.GetString("Street name and number"); 
			info.Town        = Catalog.GetString("City name and ZIP code");	
			info.Date        = DateTime.Now;
			info.DefaultName = Catalog.GetString("Primary substance name");
			info.LatinName   = Catalog.GetString("Latin substance name");
			info.Batch       = "ABCDEFG-1234567";
			info.CorrectionFactor = (0.999).ToString(info.Culture);
			info.TestId      = "888888888888";
			info.Pzn		 = "123456789012345678";
			info.User        = "Lieschen Müller";
			info.Supplier    = "Snake Oil Ltd.";
			info.ExpireDate  = DateTime.Now;
			info.Comment     = Catalog.GetString("Comment");
			info.Serial      = "Serial";
			info.Version     = "Version";
			info.MatchId	 = String.Empty;
			info.MatchRating = 0.0;

			info.Rating       = 1.0;
			info.MinRating    = 0.98;
			info.IsMatch      = true;
			info.IsMeasurable = true;
			info.ReportCountry= report_country;
			info.Label		  = new Label(info, true);

			info.Footer = Catalog.GetString("Created by QuickStep");

			this.Print(info);
		}

		public void Print(ReportInfo info)
		{
            if (this.Settings.HasPrinter == false)
				throw new Exception(Catalog.GetString("Printer settings are not valid."));
				
			this.LableInfo = info;
				
			GraphicsSize page_size = new GraphicsSize()
			{
				Width  = this.Settings.PaperWidthMM,
				Height = this.Settings.PaperHeightMM,
			};
				
			GraphicsPoint page_offset = new GraphicsPoint()
			{
				X = this.Settings.X_IndentMM,
				Y = this.Settings.Y_IndentMM,
			};
				
			int orientation = ((int)this.Settings.Orientation) * 90;
				
			Printing print_job = null;

			string doc_name = "test";
            if (String.IsNullOrEmpty(info.PdfFileFullName) == false)
                doc_name = Path.GetFileNameWithoutExtension(info.PdfFileFullName);
				
			if(EnvironmentInfo.OS == OperatingSystem.Linux)
				print_job = new LinuxPrinting(this.Settings.PrinterName, doc_name, page_size, page_offset, orientation, this.CreateLabelGraphics);
			else
				print_job = new WindowsPrinting(this.Settings.PrinterName, doc_name ,page_size, this.CreateLabelGraphics);	
				
			print_job.PrintData();
		}	
			
		private GraphicsObject CreateLabelGraphics(GraphicsRectangle area, GenericGraphicCompiler compiler)
		{
			ReportInfo info = this.LableInfo;			
				
			double label_width 	= 480;
			double label_height = 240;
				
			double offset_x 	= this.Settings.X_IndentMM / 25.4 * compiler.ReferenceDpi;
			double offset_y 	= this.Settings.Y_IndentMM / 25.4 * compiler.ReferenceDpi;
				
			double scale_factor = this.Settings.Scale;
			double rotate 		= 0;
			double translate_x	= 0;
			double translate_y	= 0;
				
			double draw_offset_x = 0.025 * area.Width;
			double draw_offset_y = 0.025 * area.Height;
				
			double draw_width 	= 0.95 * area.Width;
			double draw_height 	= 0.95 * area.Height;
				
			switch(this.Settings.Orientation)
			{

			case PrinterOrientation.Degree_0:
				rotate = 0;
				scale_factor *= Math.Min(draw_width / label_width, draw_height / label_height);
				translate_x = 0;
				translate_y = 0;
				break;
					
			case PrinterOrientation.Degree_90:
				rotate = 90;
				scale_factor *= Math.Min(draw_width / label_height, draw_height / label_width);
				translate_x = 0;
				translate_y = -draw_width;
				break;
					
			case PrinterOrientation.Degree_180:
				rotate = 180;
				scale_factor *= Math.Min(draw_width / label_width, draw_height / label_height);
				translate_x = -draw_width;
				translate_y = -draw_height;
				break;
					
			case PrinterOrientation.Degree_270:
				rotate = 270;
				scale_factor *= Math.Min(draw_width / label_height, draw_height / label_width);
				translate_x = -draw_height;
				translate_y = 0;
				break;
					
			default:
				break;
					
			}

			GraphicsGroup visual_tree_root = new GraphicsGroup();
				
			//Debug start
			/*
			GraphicsShapeRectangle background = new GraphicsShapeRectangle(draw_offset_x, draw_offset_y, draw_width, draw_height);
			background.Brush = new GraphicsSolidColorBrush(new GraphicsColor(0,0,1,0.2));
			background.Pen = new GraphicsPen(new GraphicsColor(0,0,1));
			visual_tree_root.Children.Add(background);
				
			GraphicsShapeLine line1 = new GraphicsShapeLine(draw_offset_x,draw_offset_y, draw_width + draw_offset_x, draw_height + draw_offset_y);
			line1.Pen = new GraphicsPen(GraphicsColors.Red, 2);
			visual_tree_root.Children.Add(line1);
				
			GraphicsShapeLine line2 = new GraphicsShapeLine(draw_offset_x, draw_offset_y + draw_height, draw_width + draw_offset_x, draw_offset_y);
			line2.Pen = new GraphicsPen(GraphicsColors.Red, 1);
			visual_tree_root.Children.Add(line2); 
			*/             
			//Debug end
				
			//Only for the stupid brother printer

			GraphicsShapeCircle circle = new GraphicsShapeCircle()
			{
				Radius = 0.5,
				X = area.Width / 2,
				Y = area.Height,
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
			};
			visual_tree_root.Children.Add(circle);
				
				
			GraphicsGroup main = new GraphicsGroup();
			//First move to available drawing area
			main.TransformGroup.Add(new GraphicsTranslate(draw_offset_x, draw_offset_y));
			//Second rotate the available drawing area
			main.TransformGroup.Add(new GraphicsRotate(rotate));
			//Third  move available drawing area back in visible range
			main.TransformGroup.Add(new GraphicsTranslate(translate_x, translate_y));
			//Fourth adapt the available drawing area to the given label area
			main.TransformGroup.Add(new GraphicsScale(scale_factor, scale_factor));
			//Fifth move to the userdefined offsets
			main.TransformGroup.Add(new GraphicsTranslate(offset_x / scale_factor, offset_y / scale_factor));
			visual_tree_root.Children.Add(main);
				
			//Debug start
			/*
			GraphicsShapeRectangle label = new GraphicsShapeRectangle(0, 0, label_width, label_height);
			label.Brush = new GraphicsSolidColorBrush(new GraphicsColor(0,1,0,0.2));
			label.Pen = new GraphicsPen(new GraphicsColor(0,1,0, 0.7));
			main.Children.Add(label);
			*/   
			//Debug end
				

			double x_pos0 = 5;
            double x_pos1 = 170;
            double x_pos2 = 250;
            double x_pos3 = 310;
            double y_pos = 20;
				
			double font_size = 15;
            double line_factor = 1.35;
            double small_font_factor = 0.9;
            double line_feed = line_factor * font_size;
				
			//Header
			if (info.IsMeasurable == true)
				main.Children.Add(this.DrawLogo(x_pos0 + 40, y_pos, 0.85));
				
			//create fonts
				
			GraphicsFont bold_font = new GraphicsFont()
			{
				FontName = "Helvetica",
				FontSize = font_size,
				FontWeight = GraphicsFontWeights.Bold,
			};
				
			GraphicsFont normal_font = new GraphicsFont()
			{
				FontName =  "Helvetica",
				FontSize = font_size,
				FontWeight = GraphicsFontWeights.Normal,
			};
				
			GraphicsFont small_font = new GraphicsFont()
			{
				FontName =  "Helvetica",
				FontSize = font_size * small_font_factor,
				FontWeight = GraphicsFontWeights.Normal,
			};
				
			GraphicsText text = null;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = bold_font,
				Position = new GraphicsPoint(info.IsMeasurable == true ? x_pos1 -  20 : x_pos0, y_pos + 3),
				Text = info.Label.Header,
			};
			main.Children.Add(text);
				
			GraphicsShapeLine first_line = new GraphicsShapeLine(x_pos0, y_pos + 27,  label_width - 2 * x_pos0 , y_pos + 27);
			first_line.Pen = new GraphicsPen(GraphicsColors.Black, 1);
			main.Children.Add(first_line); 
	
				
			//Body
			y_pos += 30;
			double available_height = label_height - y_pos - 5;
			double available_wdith = label_width - 2 * x_pos0;
			font_size = this.CalcFontsizeVertically(font_size, available_height, line_factor, small_font_factor, compiler);
			font_size = this.CalcFontsizeHorizontally(font_size, available_wdith ,ref x_pos1, ref x_pos2, ref x_pos3, compiler);
			bold_font.FontSize = font_size;
			normal_font.FontSize = font_size;
			small_font.FontSize = font_size * small_font_factor;
			line_feed = font_size * line_factor;
				
				
			//line 1
			line_feed = font_size * line_factor;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = bold_font,
				Text = info.DefaultName,
			};
				
			if(compiler.MeasureText(text).Width > label_width - x_pos1 - x_pos0)
			{
				text.MaxWidth = label_width - 2 * x_pos0;
				text.Position = new GraphicsPoint(x_pos0, y_pos);
				main.Children.Add(text);
			}
			else
			{
				text.Position = new GraphicsPoint(x_pos1, y_pos);
				main.Children.Add(text);
					
				text = new GraphicsText()
				{
					Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
					Font = normal_font,
					Position = new GraphicsPoint(x_pos0, y_pos),
					Text = this.LableInfo.Label.Substance,
				};
				main.Children.Add(text);
			}
				
			//line 2
			y_pos += line_feed;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				Text =  this.LableInfo.Label.Identified,
			};
			main.Children.Add(text);
			
			if (info.CustomerResult == true)
			{
				text = new GraphicsText()
				{
					Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
					Font = normal_font,
					Position = new GraphicsPoint(x_pos1, y_pos),
					Text = this.LableInfo.Label.EvalYes,
				};
				main.Children.Add(text);
			}
			else
			{
				double no_indent = 50;
				GraphicsShapeRectangle yes_rect = new GraphicsShapeRectangle();
				yes_rect.Coordinates.X = x_pos1;
				yes_rect.Coordinates.Y = y_pos + 4;
				yes_rect.Coordinates.Width = normal_font.FontSize;
				yes_rect.Coordinates.Height = normal_font.FontSize;
				yes_rect.Pen = new GraphicsPen(GraphicsColors.Black, 1);
				main.Children.Add(yes_rect);
				
				text = new GraphicsText()
				{
					Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
					Font = normal_font,
					Position = new GraphicsPoint(x_pos1 + normal_font.FontSize * 1.3, y_pos),
					Text = this.LableInfo.Label.EvalYes,
				};
				main.Children.Add(text);
				
				GraphicsShapeRectangle no_rect = new GraphicsShapeRectangle();
				no_rect.Coordinates.X = x_pos1 + no_indent;
				no_rect.Coordinates.Y = y_pos + 4;
				no_rect.Coordinates.Width = normal_font.FontSize;
				no_rect.Coordinates.Height = normal_font.FontSize;
				no_rect.Pen = new GraphicsPen(GraphicsColors.Black, 1);
				main.Children.Add(no_rect);
				
				text = new GraphicsText()
				{
					Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
					Font = normal_font,
					Position = new GraphicsPoint(x_pos1 + normal_font.FontSize * 1.3 + no_indent, y_pos),
					Text = this.LableInfo.Label.EvalNo,
				};
				main.Children.Add(text);
				
			}
			
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos2, y_pos),
				Text =  this.LableInfo.Label.Date,
			};
			main.Children.Add(text);
			
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = bold_font,
				Position = new GraphicsPoint(x_pos3, y_pos),
				Text = this.LableInfo.Label.DateContent,
			};
			main.Children.Add(text);	
				
			//line 3
			y_pos += line_feed;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				Text =  this.LableInfo.Label.TestId,
			};
			main.Children.Add(text);
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos1, y_pos),
				Text = info.TestId,
			};
			main.Children.Add(text);
				
			if (String.IsNullOrEmpty(LableInfo.Pzn) == false)
			{
				text = new GraphicsText()
				{
					Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
					Font = normal_font,
					Position = new GraphicsPoint(x_pos2, y_pos),
					Text =  this.LableInfo.Label.PPN,
				};
				main.Children.Add(text);
					
				text = new GraphicsText()
				{
					Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
					Font = normal_font,
					Position = new GraphicsPoint(x_pos3, y_pos),
					Text = info.Pzn.Replace(" ", String.Empty).Replace("-", String.Empty),
				};
				main.Children.Add(text);
			}
				
				
			//line 4
			y_pos += line_feed;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				Text =  this.LableInfo.Label.UseByDate,
			};
			main.Children.Add(text);
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos1, y_pos),
				Text = this.LableInfo.Label.ExpiryDateContent,
			};
			main.Children.Add(text);
         
            text = new GraphicsText()
            {
                Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
                Font = normal_font,
				Position = new GraphicsPoint(x_pos2, y_pos),
                Text = this.LableInfo.Label.Batch,
            };
            main.Children.Add(text);

            text = new GraphicsText()
            {
                Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
                Font = normal_font,
				Position = new GraphicsPoint(x_pos3, y_pos),
                Text = info.Batch,
            };
            main.Children.Add(text);

				
			//line 5
			y_pos += line_feed;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				Text =  this.LableInfo.Label.CorrectionFactor,
			};
			main.Children.Add(text);
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos1, y_pos),
				Text = info.CorrectionFactor,
			};
			main.Children.Add(text);
				
			//line 6
			y_pos += line_feed;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				Text =  this.LableInfo.Label.Supplier,
			};
			main.Children.Add(text);
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos1, y_pos),
				Text = info.Supplier,
				MaxWidth = label_width - x_pos1 - x_pos0,
			};
			main.Children.Add(text);
				
			//line 6
			y_pos += line_feed;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				Text =  this.LableInfo.Label.Comment,
			};
			main.Children.Add(text);
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = normal_font,
				Position = new GraphicsPoint(x_pos1, y_pos),
				Text = info.Comment,
				MaxWidth = label_width - x_pos1 - x_pos0,
			};
			main.Children.Add(text);
				
			//Footer
			y_pos += line_feed + 3;
				
			GraphicsShapeLine second_line = new GraphicsShapeLine(x_pos0,  y_pos,  label_width - 2 * x_pos0 , y_pos);
			second_line.Pen = new GraphicsPen(GraphicsColors.Black, 1);
			main.Children.Add(second_line); 
				
			y_pos += 4;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = small_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				MaxWidth = label_width - 2 * x_pos0,
			};

			if (String.IsNullOrEmpty(this.LableInfo.Company) || String.IsNullOrEmpty(this.LableInfo.Street) || String.IsNullOrEmpty(this.LableInfo.Town))
				text.Text = String.Empty;
			else
				text.Text = this.LableInfo.Company + ", " + this.LableInfo.Street  + ", " + this.LableInfo.Town;

			main.Children.Add(text);
				
			/*
			y_pos += small_font_factor * line_feed;
				
			text = new GraphicsText()
			{
				Brush = new GraphicsSolidColorBrush(GraphicsColors.Black),
				Font = small_font,
				Position = new GraphicsPoint(x_pos0, y_pos),
				MaxWidth = label_width - 2 * x_pos0,
			};
				
			if (String.IsNullOrEmpty(LabelPrinter.PdfFile))
				text.Text = Catalog.GetString("filename");
			else
				text.Text = Path.GetFileName(LabelPrinter.PdfFile);
				
			main.Children.Add(text);
			*/
				
			return visual_tree_root;
		}
			
			
		private double CalcFontsizeVertically(double font_size, double useable_height, double line_factor, double small_font_factor, GenericGraphicCompiler compiler)
		{
			double calculated_fontsize 		= font_size;
			double calculated_height 		= 0;
			GraphicsFont small_font = new GraphicsFont()
			{
				FontName = "Helvetica",
				FontSize = font_size * small_font_factor,
				FontWeight = GraphicsFontWeights.Normal,
			};
				
			GraphicsText test_text = new GraphicsText
			{
				Font = small_font,
				Text = "ABCDEFGHIJKLMNOPQRSTUVW",
			};
				
			for(;;)
			{
				small_font.FontSize = small_font_factor * calculated_fontsize;
				calculated_height = compiler.MeasureText(test_text).Height;
				calculated_height += line_factor * calculated_fontsize * small_font_factor;
				calculated_height += 7 * line_factor * calculated_fontsize;
					
				if(calculated_fontsize < 6 || calculated_height <= useable_height)
					break;
					
				calculated_fontsize -= 0.5;
			}
			return calculated_fontsize;
		}
			
		private double CalcFontsizeHorizontally(double font_size, double useable_width, ref double pos1, ref double pos2, ref double pos3, GenericGraphicCompiler compiler)
		{
			double calculated_fontsize 		= font_size;
			double calculated_width 		= 0;
			GraphicsFont normal_font = new GraphicsFont()
			{
				FontName = "Helvetica",
				FontSize = font_size,
				FontWeight = GraphicsFontWeights.Normal,
			};
				
			GraphicsText test_text1 = new GraphicsText
			{
				Font = normal_font,
				Text = this.LableInfo.Label.Supplier,
			};
				
			GraphicsText test_text2 = new GraphicsText
			{
				Font = normal_font,
				Text = "Nein",
			};
				
			GraphicsText test_text3 = new GraphicsText
			{
				Font = normal_font,
				Text =  this.LableInfo.Label.Batch,
			};
				
			GraphicsText test_text4 = new GraphicsText
			{
				Font = normal_font,
				Text = "888888888888888888",
			};
	
			for(;;)
			{
				 normal_font.FontSize = calculated_fontsize;
				pos1 = compiler.MeasureText(test_text1).Width + 10;
				pos2 = pos1 + compiler.MeasureText(test_text2).Width + 65 + 1.3 * calculated_fontsize;
				pos3 = pos2 + compiler.MeasureText(test_text3).Width + 5;
				calculated_width = pos3 + compiler.MeasureText(test_text4).Width;
					
				if (calculated_fontsize < 6 || calculated_width <= useable_width)
					break;
					
				calculated_fontsize -= 0.5;
			}
			return calculated_fontsize;
		}
			




		private GraphicsGroup DrawLogo(double xoff, double yoff, double scale)
		{
			using (StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("ApoIdent.Resources.Others.Label_Apo-Ident.csv")))
			{
				GraphicsGroup group = new GraphicsGroup();
				group.TransformGroup.Add(new GraphicsTranslate(xoff, yoff));
				group.TransformGroup.Add(new GraphicsScale(scale, scale));
					
					                         
				List<GraphicsPoint> points = new List<GraphicsPoint>();
					
				Regex regex = new Regex(",");
				System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-US");
				string line;
					
				while (!string.IsNullOrEmpty(line = reader.ReadLine()))
				{
					try
					{
						string[] s = regex.Split(line);
						points.Add(new GraphicsPoint(Double.Parse(s[0], culture), -Double.Parse(s[1], culture))); 
					}
					catch(Exception)
					{
						GraphicsShapePolygone polygone = new GraphicsShapePolygone(points);
						polygone.Brush = new GraphicsSolidColorBrush(GraphicsColors.Black);
						polygone.Pen = new GraphicsPen(GraphicsColors.Black);
						group.Children.Add(polygone);
						points.Clear();
					}
				}
					
				GraphicsShapePolygone last_polygone = new GraphicsShapePolygone(points);
				last_polygone.Brush = new GraphicsSolidColorBrush(GraphicsColors.Black);
				last_polygone.Pen = new GraphicsPen(GraphicsColors.Black);
				group.Children.Add(last_polygone);
					
				return group;
				}
		}

		public static List<string> PrinterNames
		{
			get
			{
				List<string> printers = new List<string> ();
				try
				{
					
					foreach (string name in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
						printers.Add(name);
				}
				catch(Exception)
				{
					printers = new List<string> ();
				}

				printers.Sort();
                printers.Insert(0, Catalog.GetString("None"));
				return printers;
			}
		}

		public static Dictionary<string, PaperSize> GetPaperSizes(string printer_name)
		{
            var printer = System.Drawing.Printing.PrinterSettings.InstalledPrinters; //work around for refresh paper names
           
            Dictionary<string, PaperSize> tmp = new Dictionary<string, PaperSize>();

			try 
			{
                PrintDocument pd = new PrintDocument();
				pd.PrinterSettings.PrinterName = printer_name;
				
				foreach (PaperSize paper_size in pd.PrinterSettings.PaperSizes)
					tmp.Add(paper_size.PaperName, paper_size);
				pd.Dispose();
			}
			catch(Exception)
			{                
			}

            if (tmp.Count == 0)
            {
                PaperSize user_defined = new PaperSize();
                user_defined.PaperName = LabelPrinter.USER_DEFINED_SIZE_NAME;
                user_defined.Width = (int)(LabelPrinter.USER_DEFINED_DEFAULT_WIDTH * 100 / 25.4);
                user_defined.Height = (int)(LabelPrinter.USER_DEFINED_DEFAULT_HEIGHT * 100 / 25.4);
                tmp.Add(user_defined.PaperName, user_defined);
            }

            return tmp;
		}

        public static event EventHandler PrinterProcessExited = null;

        public static void StartLabelPrinterSettingsDialog(string printer_name, string paper_name)
		{
            System.Diagnostics.Process control = new System.Diagnostics.Process();

			PlatformID osversion = Environment.OSVersion.Platform;
			if (osversion == PlatformID.Win32NT      ||
				osversion == PlatformID.Win32S       ||
				osversion == PlatformID.Win32Windows ||
				osversion == PlatformID.WinCE)
			{
				// windows
				control.StartInfo.FileName = "rundll32.exe";
				control.StartInfo.Arguments = "printui.dll,PrintUIEntry /e /n\"" + printer_name + "\"";
			}
			else
			{
				// linux
				control.StartInfo.FileName  = "system-config-printer";
					//					control.StartInfo.Arguments = "--configure-printer=\"" + this.label_printer_combo.ActiveText + "\"";
			}

            string[] parameters = new string[] { printer_name, paper_name };

			control.StartInfo.CreateNoWindow  = false;
			control.StartInfo.UseShellExecute = false;
			control.StartInfo.RedirectStandardOutput = false;
            control.EnableRaisingEvents = true;
            control.Exited += (sender, e) => 
            {
                if (LabelPrinter.PrinterProcessExited != null)
                    LabelPrinter.PrinterProcessExited(parameters, EventArgs.Empty);
            };

			control.Start();	
		}
			
		private  ReportInfo LableInfo	{get;set;}
		private LabelPrinterSettings Settings {get; set;}
	}
}

