//
//  Plugin.cs
//
// QuickStep: Acquire, view and identify spectra 
// Copyright (C) 2010-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.Reflection;
using System.IO;
using System.Text;
using Gtk;
using Mono.Unix;

using Hiperscan.Extensions;
using Hiperscan.SGS;


namespace Hiperscan.Extensions.OnlineProcessing
{

	public class Plugin : IPlugin
	{
		public static readonly string name    = Catalog.GetString("Online Processing");
		public static readonly string version = "1.0.0";
		public static readonly string vendor  = "Hiperscan GmbH";
		public static readonly string description = Catalog.GetString("Process acquired spectra online");
		public static readonly string guid = "aeafe6c3-a2ba-4789-8770-4cef35662fe0";
		
		internal static IHost host;
		internal static SpinButton acquisition_count_spin;
		private MenuInfo[] menu_infos;
		private ToolbarInfo[] toolbar_infos;
		private bool active = true;

//		private static bool run_stream = false;

		
		public Plugin ()
		{
			MenuInfo menu_info1 = new MenuInfo(Catalog.GetString("Acquire Solid Spectrum"));
			menu_info1.WatchCursor = true;
			menu_info1.NeedIdleDevice = true;
			menu_info1.NeedSingleDevice = false;
			menu_info1.Invoked += delegate(object sender, EventArgs e) {
				foreach (Device dev in Plugin.host.ActiveDevices.Idle)
				{
					if (dev.IsFinder)
						OnlineProcessing.Acquire(dev, false, false, 1, 0);
				}
			};
			
			MenuInfo menu_info2 = new MenuInfo(Catalog.GetString("Acquire Empty Die Spectrum"));
			menu_info2.WatchCursor = true;
			menu_info2.NeedIdleDevice = true;
			menu_info2.NeedSingleDevice = false;
			menu_info2.Invoked += delegate(object sender, EventArgs e) {
				foreach (Device dev in Plugin.host.ActiveDevices.Idle)
				{
					if (dev.IsFinder)
						OnlineProcessing.AcquireEmptyDie(dev);
				}
			};
			
			MenuInfo menu_info3 = new MenuInfo(Catalog.GetString("Acquire Fluid Spectrum"));
			menu_info3.WatchCursor = true;
			menu_info3.NeedIdleDevice = true;
			menu_info3.NeedSingleDevice = false;
			menu_info3.Invoked += delegate(object sender, EventArgs e) {
				foreach (Device dev in Plugin.host.ActiveDevices.Idle)
				{
					if (dev.IsFinder)
						OnlineProcessing.Acquire(dev, true, false, 1, 0);
				}
			};

			MenuInfo menu_info4 = new MenuInfo(Catalog.GetString("Reset References"));
			menu_info4.WatchCursor = false;
			menu_info4.NeedIdleDevice = false;
			menu_info4.NeedSingleDevice = false;
			menu_info4.Invoked += delegate(object sender, EventArgs e) {
				OnlineProcessing.Reset();
			};
			
			this.menu_infos = new MenuInfo[] {menu_info1, menu_info2, menu_info3, menu_info4};
			
//			ToolButton b = new ToolButton(new Label("O:>"), string.Empty);
//			ToolbarInfo toolbar_info01 = new ToolbarInfo(b, 
//			                                             Catalog.GetString("O:Stream"),
//			                                             Catalog.GetString("Acquire and process spectrum stream (solid)"));
//			toolbar_info01.WatchCursor = true;
//			toolbar_info01.NeedIdleDevice = true;
//			toolbar_info01.NeedSingleDevice = false;
//			toolbar_info01.Invoked += delegate(object sender, EventArgs e) {
//				run_stream = true;
//				while (run_stream)
//				{
//					foreach (Device dev in Plugin.host.ActiveDevices.Idle)
//					{
//						if (dev.IsFinder)
//						{
//							OnlineProcessing.Acquire(dev, false, true);
//						}
//					}
//					Plugin.host.ProcessEvents();
//				}
//			};
//
//			b = new ToolButton(new Label("O:#"), string.Empty);
//			ToolbarInfo toolbar_info02 = new ToolbarInfo(b, 
//			                                             Catalog.GetString("O:Stop"),
//			                                             Catalog.GetString("Stop running spectrum stream (solid)"));
//			toolbar_info02.WatchCursor = false;
//			toolbar_info02.NeedIdleDevice = false;
//			toolbar_info02.NeedSingleDevice = false;
//			toolbar_info02.Invoked += delegate(object sender, EventArgs e) {
//				run_stream = false;
//			};

			Plugin.acquisition_count_spin = new SpinButton(1f, 20f, 1f);
			Plugin.acquisition_count_spin.WidthChars = 2;
			Alignment align = new Alignment(0.5f, 0.5f, 0f, 0f);
			align.Add(Plugin.acquisition_count_spin);
			ToolItem item = new ToolItem();
			item.Add(align);
			ToolbarInfo toolbar_info0 = new ToolbarInfo(item,
			                                            Catalog.GetString("Acquisition count"),
			                                            Catalog.GetString("Specify number of spectra to acquire"));
			toolbar_info0.NeedIdleDevice = true;


			ToolButton b = new ToolButton(new Label("O:S"), string.Empty);
			ToolbarInfo toolbar_info1 = new ToolbarInfo(b, 
			                                            Catalog.GetString("O:Solid"),
			                                            Catalog.GetString("Acquire and process spectrum (solid)"));
			toolbar_info1.WatchCursor = true;
			toolbar_info1.NeedIdleDevice = true;
			toolbar_info1.NeedSingleDevice = false;
			toolbar_info1.Invoked += delegate(object sender, EventArgs e) {
				Plugin.acquisition_count_spin.Update();
				for (int ix=0; ix < Plugin.acquisition_count_spin.Value; ++ix)
				{
					foreach (Device dev in host.ActiveDevices.Connected)
					{
						if (dev.IsFinder)
							OnlineProcessing.Acquire(dev, false, false, (int)Plugin.acquisition_count_spin.Value, ix);
					}
				}
			};
			
			b = new ToolButton(new Label("O:E"), string.Empty);
			ToolbarInfo toolbar_info2 = new ToolbarInfo(b, 
			                                            Catalog.GetString("O:Empty Die"),
			                                            Catalog.GetString("Acquire empty die spectrum (fluid)"));
			toolbar_info2.WatchCursor = true;
			toolbar_info2.NeedIdleDevice = true;
			toolbar_info2.NeedSingleDevice = false;
			toolbar_info2.Invoked += delegate(object sender, EventArgs e) {
				foreach (Device dev in Plugin.host.ActiveDevices.Idle)
				{
					if (dev.IsFinder)
						OnlineProcessing.AcquireEmptyDie(dev);
				}
			};

			b = new ToolButton(new Label("O:F"), string.Empty);
			ToolbarInfo toolbar_info3 = new ToolbarInfo(b, 
			                                            Catalog.GetString("O:Fluid"),
			                                            Catalog.GetString("Acquire and process spectrum (fluid)"));
			toolbar_info3.WatchCursor = true;
			toolbar_info3.NeedIdleDevice = true;
			toolbar_info3.NeedSingleDevice = false;
			toolbar_info3.Invoked += delegate(object sender, EventArgs e) {
				Plugin.acquisition_count_spin.Update();
				for (int ix=0; ix < Plugin.acquisition_count_spin.Value; ++ix)
				{
					foreach (Device dev in host.ActiveDevices.Connected)
					{
						if (dev.IsFinder)
							OnlineProcessing.Acquire(dev, true, false, (int)Plugin.acquisition_count_spin.Value, ix);
					}
				}
			};

			this.toolbar_infos = new ToolbarInfo[] {toolbar_info0, toolbar_info1, toolbar_info2, toolbar_info3};
		}
		
		public void ReplaceGui()
		{
		}
		
		public MenuInfo[] MenuInfos
		{
			get { return this.menu_infos; }
		}
		
		public ToolbarInfo[] ToolbarInfos
		{
			get { return this.toolbar_infos; }
		}

		public PlotTypeInfo[] PlotTypeInfos
		{
			get { return null; }
		}
		
		public FileTypeInfo[] FileTypeInfos
		{
			get { return null; }
		}

		public void Initialize(IHost host)
		{
			Plugin.host = host;

			Settings.Init();
			Plugin.acquisition_count_spin.Value = Settings.Current.AcquisitionCount;
			Plugin.acquisition_count_spin.Changed += delegate(object sender, EventArgs e) {
				Settings.Current.AcquisitionCount = (int)Plugin.acquisition_count_spin.Value;
			};
		}
		
		public string Name
		{
			get { return Plugin.name; }
		}
		
		public string Version
		{
			get { return Plugin.version; }
		}
		
		public string Vendor
		{
			get { return Plugin.vendor; }
		}

		public Assembly Assembly
		{
			get { return Assembly.GetExecutingAssembly(); }
		}

		public string Description
		{
			get { return Plugin.description; }
		}
		
		public Guid Guid
		{
			get { return new Guid(Plugin.guid); }
		}
		
		public bool Active
		{
			get { return this.active;  }
			set { this.active = value; }
		}

		public bool CanReplaceGui
		{
			get { return false; }
		}
	}
}
