// 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.Reflection;
using System.IO;

using Hiperscan.GtkExtensions.Compiler;
using Hiperscan.Unix;


namespace Hiperscan.GtkExtensions.Widgets
{	
	
	public enum FinderSplashScreenStates
	{
		Hiperscan,
		ApoIdent,
		WarmUp,
		WarmUpCancelled,
	}
	
	public class FinderSplashScreen : Gtk.DrawingArea
	{
		private MeasureTextDelegate MeasureText{get;set;}
		private ShortOSVersion CurrentOSVersion {get;set;}
		public  int Width 	{get; private set;}
		public int Height 	{get; private set;}
		
		public FinderSplashScreen ()
		{
			this.Width = 504;
			this.Height = 207;
			this.WidthRequest = 504;
			this.HeightRequest = 207;
			
			
			switch(Environment.OSVersion.Platform)
			{
			case PlatformID.Win32NT:
			case PlatformID.Win32S:
			case PlatformID.Win32Windows:
			case PlatformID.WinCE:
			case PlatformID.Xbox:
				this.CurrentOSVersion = ShortOSVersion.Windows;
				this.MeasureText = SystemDrawingGraphicCompiler.MeasureGraphicsText;
				break;
				
			default:
				this.CurrentOSVersion = ShortOSVersion.Linux;
				this.MeasureText = MonoCairoGraphicCompiler.MeasureGraphicsText;
				break;
			}
				
			this.InitializeImages();
			this.InitVisualTreeRoot();	
			this.Update(FinderSplashScreenStates.Hiperscan);
		}
		
		private void InitializeImages()
		{
			byte[] buf = new byte[8192];

			string tmp_hiperscan = System.IO.Path.GetTempFileName();
			using (FileStream fs_hiperscan = new FileStream(tmp_hiperscan, FileMode.Create, FileAccess.Write))
			{
				Stream src_hiperscan = Assembly.GetExecutingAssembly().GetManifestResourceStream("GtkExtensions.Widgets.FinderSplashScreen.splash_screen_hiperscan.png");
            	for (;;)
            	{
	                int num = src_hiperscan.Read(buf, 0, buf.Length);
	                if (num == 0)
	                    break;
	                fs_hiperscan.Write(buf, 0, num);
				}
            }
			this.BackGroundHiperscan = new GraphicsImage();
			this.BackGroundHiperscan.Coordinates = new GraphicsRectangle(-2, -2, this.Width + 4, this.Height + 4);
			this.BackGroundHiperscan.FileName = tmp_hiperscan;
			try{File.Delete(tmp_hiperscan);}catch(Exception){}
			
			string tmp_apo_ident = System.IO.Path.GetTempFileName();
			using (FileStream fs_apo_ident = new FileStream(tmp_apo_ident, FileMode.Create, FileAccess.Write))
			{
				Stream src_apo_ident = Assembly.GetExecutingAssembly().GetManifestResourceStream("GtkExtensions.Widgets.FinderSplashScreen.splash_screen_apo_ident.png");
            	for (;;)
            	{
	                int num = src_apo_ident.Read(buf, 0, buf.Length);
	                if (num == 0)
	                    break;
	                fs_apo_ident.Write(buf, 0, num);
				}
            }
			this.BackgroundApoIdent = new GraphicsImage();
			this.BackgroundApoIdent.Coordinates = new GraphicsRectangle(-1, -1, this.Width + 2, this.Height + 2);
			this.BackgroundApoIdent.FileName = tmp_apo_ident;
			try{File.Delete(tmp_apo_ident);}catch(Exception){}
		}
		
		
		private void InitVisualTreeRoot()
		{
			this.VisualTreeRoot = new  GraphicsGroup();
			
			GraphicsFont normal_font = new GraphicsFont();
			normal_font.FontWeight = GraphicsFontWeights.Normal;
			normal_font.FontSize = 18;
			
			this.Label = new GraphicsText();
			this.Label.Font = normal_font;
			this.Label.Position.Y = 160;
			this.Label.Brush = new GraphicsSolidColorBrush(GraphicsColors.White);
		
		}
		
		protected override bool OnExposeEvent (Gdk.EventExpose evnt)
		{
			GenericGraphicCompiler translator = null;
			if (this.CurrentOSVersion == ShortOSVersion.Windows)
				translator = new SystemDrawingGraphicCompiler(Gtk.DotNet.Graphics.FromDrawable(evnt.Window, true));
			else
				 translator = new MonoCairoGraphicCompiler(Gdk.CairoHelper.Create(evnt.Window));

			
			GraphicsCompiler graphic_compiler = new GraphicsCompiler(this.VisualTreeRoot, translator);
			graphic_compiler.TraverseVisualTree();	
			translator.Dispose();
			
			return true;
		}
		
		public void  Update(FinderSplashScreenStates state)
		{
			this.Update(state, 0);
		}
		
		public void Update(FinderSplashScreenStates state, double temperature)
		{
			this.VisualTreeRoot.Children.Clear();
			switch(state)
			{
			case FinderSplashScreenStates.Hiperscan:
				this.VisualTreeRoot.Children.Add(this.BackGroundHiperscan);
				this.Label.Text = String.Format("Copyright \u00A9 Hiperscan GmbH 2010 - {0}", DateTime.Now.ToString("yyyy"));
				break;
				
			case FinderSplashScreenStates.ApoIdent:
				this.VisualTreeRoot.Children.Add(this.BackgroundApoIdent);
				this.Label.Text = Catalog.GetString("is starting and will be ready in a few seconds ...");
				break;
				
			case FinderSplashScreenStates.WarmUp:
				this.VisualTreeRoot.Children.Add(this.BackgroundApoIdent);
				this.Label.Text = String.Format(Catalog.GetString("is warming up ({0:F1}°C). Please wait ..."), temperature);
				break;
				
			case FinderSplashScreenStates.WarmUpCancelled:
				this.VisualTreeRoot.Children.Add(this.BackgroundApoIdent);
				this.Label.Text = Catalog.GetString("is cancelling warm-up. Please wait ...");
				break;				
			}
			
			GraphicsSize size = this.MeasureText(this.Label);
			this.Label.Position.X = (this.Width - size.Width) / 2;
			this.VisualTreeRoot.Children.Add(this.Label);

			this.QueueDraw();
		}
		
		private Gdk.Pixbuf HiperscanPixBuf			{get; set;}
		private Gdk.Pixbuf ApoIdentPixBuf			{get; set;}
		
		private Stream HiperscanBitmap				{get; set;}
		private Stream ApoIdentBitmap				{get; set;}
		
		private GraphicsGroup VisualTreeRoot 		{get; set;}
		private GraphicsImage BackGroundHiperscan 	{get; set;}
		private GraphicsImage BackgroundApoIdent	{get; set;}
		private GraphicsText Label					{get; set;}
	}
}
	