using System;
using Gtk;

namespace DMX2
{
	public partial class GestionMidiUI : Gtk.Dialog
	{

		Gtk.ListStore lsDetect;
		Gtk.ListStore lsKnown;

		uint timer=0;

		public GestionMidiUI ()
		{
			this.Build ();

			lsDetect = new Gtk.ListStore (typeof(string));
			lsKnown = new Gtk.ListStore (typeof(MidiEventProvider.MidiDev));


			var nameCol = new Gtk.TreeViewColumn ();
			var nameCell = new Gtk.CellRendererText ();
			nameCol.Title = "Interfaces";
			nameCol.PackStart (nameCell, true);
			nameCol.AddAttribute (nameCell, "text", 0);
			this.listDetect.AppendColumn (nameCol);

			var mdCol = new Gtk.TreeViewColumn ();
			var mdCell = new Gtk.CellRendererText ();
			mdCol.Title = "Interfaces";
			mdCol.PackStart (mdCell, true);
			mdCol.SetCellDataFunc (mdCell, new Gtk.TreeCellDataFunc (RenderMidiDev));
			this.listKnown.AppendColumn (mdCol);

			listDetect.Model = lsDetect;
			listKnown.Model = lsKnown;


			FillLsDetect ();
			FillLsKnown ();


			timer = GLib.Timeout.Add (500, Refresh);

			Destroyed += HandleDestroyed;


			spinNbPage.Value = Conduite.Courante.Midi.Maxpage;

			if (Conduite.Courante.Midi.UnpaginatedChannels.Count == 0) {
				spinUPCh.Sensitive = false; 
				chkPg.Active = false;
			} else {
				spinUPCh.Sensitive = true; 
				spinUPCh.Value = Conduite.Courante.Midi.UnpaginatedChannels [0] + 1;
				chkPg.Active = true;
			}

		}

		void HandleDestroyed (object sender, EventArgs e)
		{
			if(timer!=0)
			GLib.Source.Remove(timer);
		}

		bool Refresh ()
		{
			if (Conduite.Courante.Midi.GuiRefreshFlag) {
				FillLsDetect();
				FillLsKnown();
			}
			return true;
		}

		void RenderMidiDev (Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel tree_model, Gtk.TreeIter iter)
		{
			MidiEventProvider.MidiDev dev =  tree_model.GetValue (iter, 0) as MidiEventProvider.MidiDev;
			(cell as Gtk.CellRendererText).Text = dev.ConnectedPorts.Count>0
				?string.Format("{0} ({1} connectés)",dev.Name,dev.ConnectedPorts.Count)
					:string.Format("{0} (Déconnecté)",dev.Name);
		}

		void FillLsDetect ()
		{
			lsDetect.Clear ();
			foreach (var dev in AlsaSeqLib.EnumClients ()) {
				if(dev.Id== AlsaSeqLib.ClientId || dev.Id == 0 || dev.Id == 14 ) continue;
				foreach(var port in dev.Ports){
					if((port.Caps & AlsaSeqLib.SND_SEQ_PORT_CAP_READ) == AlsaSeqLib.SND_SEQ_PORT_CAP_READ){
						string name = dev.Name+":"+port.Name;
						if(!Conduite.Courante.Midi.IsKnownDevice(name))
							lsDetect.AppendValues(name);
					}
				}
			}
		}

		void FillLsKnown ()
		{
			lsKnown.Clear ();
			foreach (var dev in Conduite.Courante.Midi.KnownDevices) {
				lsKnown.AppendValues(dev);
			}
		}
		protected void OnButtonCloseClicked (object sender, EventArgs e)
		{
			Destroy();
		}		

		protected void OnListDetectCursorChanged (object sender, EventArgs e)
		{
			btnActiv.Sensitive = (listDetect.Selection.CountSelectedRows() >0);
		}		

		protected void OnListKnownCursorChanged (object sender, EventArgs e)
		{
			chkFB.Sensitive = btnDesactiv.Sensitive = (listKnown.Selection.CountSelectedRows() >0);
			TreeIter iter;
			if(!listKnown.Selection.GetSelected(out iter)) return;
			MidiEventProvider.MidiDev dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDev ;
			chkFB.Active = dev.HasFeedback;

		}		

		protected void OnBtnActivClicked (object sender, EventArgs e)
		{
			TreeIter iter;
			if(!listDetect.Selection.GetSelected(out iter)) return;
			string name= lsDetect.GetValue(iter,0) as string;
			Conduite.Courante.Midi.ConnectDevice(name);
			FillLsDetect ()	;
			FillLsKnown();

		}		

		protected void OnBtnDesactivClicked (object sender, EventArgs e)
		{
			TreeIter iter;
			if(!listKnown.Selection.GetSelected(out iter)) return;
			MidiEventProvider.MidiDev dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDev ;
			Conduite.Courante.Midi.DisconnectDevice(dev);
			FillLsDetect ()	;
			FillLsKnown();

		}		


		protected void OnChkFBToggled (object sender, EventArgs e)
		{
			TreeIter iter;
			if(!listKnown.Selection.GetSelected(out iter)) return;
			MidiEventProvider.MidiDev dev = lsKnown.GetValue(iter,0) as MidiEventProvider.MidiDev ;
			dev.HasFeedback = chkFB.Active;

			Conduite.Courante.Midi.RefreshFeedback(dev.Name);

		}
	

		protected void OnSpinNbPageValueChanged (object sender, EventArgs e)
		{
			Conduite.Courante.Midi.Maxpage = (uint) spinNbPage.ValueAsInt;
		}		

		protected void OnSpinUPChValueChanged (object sender, EventArgs e)
		{
			Conduite.Courante.Midi.UnpaginatedChannels.Clear();
			if (spinUPCh.ValueAsInt == 0) return;
			Conduite.Courante.Midi.UnpaginatedChannels.Add((byte)(spinUPCh.ValueAsInt-1));
		}		

		protected void OnChkPgToggled (object sender, EventArgs e)
		{
			Conduite.Courante.Midi.UnpaginatedChannels.Clear ();
			if (!chkPg.Active) {
				spinUPCh.Sensitive=false;
				return;
			}
			spinUPCh.Sensitive=true;
			Conduite.Courante.Midi.UnpaginatedChannels.Add((byte)(spinUPCh.ValueAsInt-1));
		}




	}
}


