using System;
using Gtk;
using System.Collections.Generic;


namespace DMX2
{
	public partial class EditionUnivers : Gtk.Dialog
	{
		UniversDMX universEdite;
		public EditionUnivers (Window parent) : base ("Edition Univers",parent,DialogFlags.DestroyWithParent)
		{
			this.Build ();
			ConstruitCBUnivers();
			ConstruitCBCircuits();
			ConstruitCBFT();
			ConstruitListeDimmer();

			ConstruitListeCircuits();
		}

		ListStore lsCbUnivers = new ListStore(typeof(UniversDMX));

		void ConstruitCBUnivers ()
		{
			cbUnivers.Model = lsCbUnivers;
			var cellCbUnivers = new CellRendererText();
			cbUnivers.PackStart(cellCbUnivers,false);
			cbUnivers.SetCellDataFunc(cellCbUnivers, new CellLayoutDataFunc(RenderUniversName));


			foreach(UniversDMX u in Conduite.Courante.Patches)
				lsCbUnivers.AppendValues(u);

			TreeIter iter;
			lsCbUnivers.GetIterFirst(out iter);
			cbUnivers.SetActiveIter(iter);

		}

		void RenderUniversName (CellLayout cell_layout, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			UniversDMX univers =  tree_model.GetValue (iter, 0) as UniversDMX;
			if(univers != null)
			(cell as Gtk.CellRendererText).Text = univers.Nom;
		}

		ListStore lsCbCircuits = new ListStore(typeof(Circuit));
		void ConstruitCBCircuits ()
		{
			cbCircuit.Model = lsCbCircuits;
			var cellCbCircuit = new CellRendererText();
			cbCircuit.PackStart(cellCbCircuit,true);
			cbCircuit.SetCellDataFunc(cellCbCircuit,new CellLayoutDataFunc(RenderCircuitName));

			lsCbCircuits.AppendValues("toto");
			foreach (Circuit c in Conduite.Courante.Circuits)
				lsCbCircuits.AppendValues(c);

		}

		void RenderCircuitName (CellLayout cell_layout, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			Circuit c =  tree_model.GetValue (iter, 0) as Circuit;
			if(c != null)
				(cell as Gtk.CellRendererText).Text = c.ID + "-" + c.Name;
			else
				(cell as Gtk.CellRendererText).Text = "--Aucun--";

		}
	
		int currDimm=0;

		ListStore lsCbFT = new ListStore(typeof(string),typeof(UniversDMX.FTransfer));
		void ConstruitCBFT ()
		{
			var values = Enum.GetValues(typeof(UniversDMX.FTransfer));
			cbFT.Model = lsCbFT;

			foreach(var v in values)
				lsCbFT.AppendValues(v.ToString(), (UniversDMX.FTransfer)v );
		}

		protected void OnCbUniversChanged (object sender, EventArgs e)
		{
			TreeIter iter;
			if(cbUnivers.GetActiveIter(out iter))
			{
				universEdite = lsCbUnivers.GetValue(iter,0) as UniversDMX;
				MajListeDimmer();
				spinDimmer.Value = 1;
				MajDimmerSelectione();
			}
		}		

		protected void OnBtAddClicked (object sender, EventArgs e)
		{
			var dlg = new Dialog ("Nom ?", this, DialogFlags.Modal);
			var entry = new Entry ("Nouvel Univers");
			dlg.AddButton (Stock.Ok, ResponseType.Ok).GrabDefault ();
			dlg.AddButton (Stock.Cancel, ResponseType.Cancel);
			dlg.VBox.Add (new Label ("Nom de la nouvelle Conduite :"));
			dlg.VBox.Add (entry);
			dlg.VBox.ShowAll (); 
			entry.ActivatesDefault = true;

			if ((ResponseType)dlg.Run () == ResponseType.Ok) {
				UniversDMX univ = new UniversDMX ();

				univ.Nom = entry.Text;	
				lsCbUnivers.AppendValues (univ);
				Conduite.Courante.Patches.Add (univ);
			}
			dlg.Destroy();
		}

		protected void OnButtonCancelClicked (object sender, EventArgs e)
		{
			Destroy();
		}


		ListStore lsDimmers = new ListStore(typeof(int),typeof(UniversDMX.Dimmer));
		void ConstruitListeDimmer ()
		{



			var idCol = new Gtk.TreeViewColumn();
			var idCell = new Gtk.CellRendererText();
			idCol.Title = "ID";
			idCol.PackStart(idCell,true);
			idCol.SetCellDataFunc(idCell, new Gtk.TreeCellDataFunc(	RenderDimmerID) );
			tvDimm.AppendColumn(idCol);

			var cirCol = new Gtk.TreeViewColumn();
			var cirCell = new Gtk.CellRendererText();
			cirCol.Title = "Circuit";
			cirCol.PackStart(cirCell,true);
			cirCol.SetCellDataFunc(cirCell, new Gtk.TreeCellDataFunc(	RenderDimmerCircuit) );
			tvDimm.AppendColumn(cirCol);

			var ftCol = new Gtk.TreeViewColumn();
			var ftCell = new Gtk.CellRendererText();
			ftCol.Title = "Fonction";
			ftCol.PackEnd(ftCell,true);
			ftCol.SetCellDataFunc(ftCell, new Gtk.TreeCellDataFunc(	RenderDimmerFT) );
			tvDimm.AppendColumn(ftCol);

			var p1Col = new Gtk.TreeViewColumn();
			var p1Cell = new Gtk.CellRendererText();
			p1Col.Title = "P1";
			p1Col.PackEnd(p1Cell,true);
			p1Col.SetCellDataFunc(p1Cell, new Gtk.TreeCellDataFunc(	RenderDimmerP1) );
			tvDimm.AppendColumn(p1Col);

			var p2Col = new Gtk.TreeViewColumn();
			var p2Cell = new Gtk.CellRendererText();
			p2Col.Title = "P2";
			p2Col.PackEnd(p2Cell,true);
			p2Col.SetCellDataFunc(p2Cell, new Gtk.TreeCellDataFunc(	RenderDimmerP2) );
			tvDimm.AppendColumn(p2Col);
			tvDimm.Model = lsDimmers;
					


		}	

		void MajListeDimmer ()
		{
			lsDimmers.Clear();
			int i; UniversDMX.Dimmer dim;
			for (i=0; i< universEdite.Dimmers.Length;i++)
			{
				dim = universEdite.Dimmers[i];

				lsDimmers.AppendValues(i+1,dim);
			}
			int id = (int)(spinDimmer.Value);
			tvDimm.SetCursor( new TreePath( new int[1] { id - 1 })   ,null,false);

		}

		void RenderDimmerID (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			int i = (int)(tree_model.GetValue (iter, 0));
			(cell as Gtk.CellRendererText).Text = i.ToString();
		}		

		void RenderDimmerCircuit (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			UniversDMX.Dimmer dim = (UniversDMX.Dimmer)(tree_model.GetValue (iter, 1));
			(cell as Gtk.CellRendererText).Text = dim.circuitAssocié==null?" - ": dim.circuitAssocié.ID + " - " + dim.circuitAssocié.Name ;
		}	
		void RenderDimmerFT (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			UniversDMX.Dimmer dim = (UniversDMX.Dimmer)(tree_model.GetValue (iter, 1));
			(cell as Gtk.CellRendererText).Text = dim.fonctionTransfert.ToString();
		}

		void RenderDimmerP1 (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			UniversDMX.Dimmer dim = (UniversDMX.Dimmer)(tree_model.GetValue (iter, 1));
			(cell as Gtk.CellRendererText).Text = dim.param1.ToString();
		}

		void RenderDimmerP2 (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			UniversDMX.Dimmer dim = (UniversDMX.Dimmer)(tree_model.GetValue (iter, 1));
			(cell as Gtk.CellRendererText).Text = dim.param2.ToString();
		}	


		protected void OnSpinDimmerValueChanged (object sender, EventArgs e)
		{
			MajDimmerSelectione();
		}

		bool majencour = false;
		void MajDimmerSelectione()
		{
			majencour = true;
			int id = (int)(spinDimmer.Value);

			currDimm = id - 1;
			tvDimm.SetCursor( new TreePath( new int[1] { currDimm  })   ,null,false);


			// recherche du circuit dans la liste et selection
			TreeIter iter;
			lsCbCircuits.GetIterFirst(out iter);
			do{
				if((lsCbCircuits.GetValue(iter,0) as Circuit) == universEdite.Dimmers[currDimm].circuitAssocié) break;
			} while (lsCbCircuits.IterNext(ref iter));
			cbCircuit.SetActiveIter(iter);

			lsCbFT.GetIterFirst(out iter);
			do{
				if((lsCbFT.GetValue(iter,0) as string) == universEdite.Dimmers[currDimm].fonctionTransfert.ToString())
					break;
			}while(lsCbFT.IterNext(ref iter));
			cbFT.SetActiveIter(iter);

			txtParam1.Text = universEdite.Dimmers[currDimm].param1.ToString();
			txtParam2.Text = universEdite.Dimmers[currDimm].param2.ToString();

			majencour = false;
		}		

		protected void OnTvDimmCursorChanged (object sender, EventArgs e)
		{
			var rows = tvDimm.Selection.GetSelectedRows();
			if(rows.Length>0)
				spinDimmer.Value = rows[0].Indices[0]+1;
		}		

		protected void OnBtPatchDroitClicked (object sender, EventArgs e)
		{
			int i; 
			int max = Math.Min(Conduite.Courante.Circuits.Count,512);

			for(i=0 ;i<max ;i++)
			{
				universEdite.Dimmers[i].circuitAssocié = Conduite.Courante.Circuits[i];
				universEdite.Dimmers[i].fonctionTransfert = UniversDMX.FTransfer.lineaire;
				universEdite.Dimmers[i].param1 = 100;
			}
			MajListeDimmer();
		}		

		protected void OnCbCircuitChanged (object sender, EventArgs e)
		{
			if(majencour) return;
			TreeIter iter;
			if (cbCircuit.GetActiveIter (out iter)) {
				Circuit c = lsCbCircuits.GetValue (iter, 0) as Circuit;
				universEdite.Dimmers[currDimm].circuitAssocié = c;
				MajListeDimmer();
			}
		}
		protected void OnCbFTChanged (object sender, EventArgs e)
		{
			if(majencour) return;
			TreeIter iter;
			if (cbFT.GetActiveIter (out iter)) {
				UniversDMX.FTransfer ft;
				UniversDMX.FTransfer.TryParse(lsCbFT.GetValue (iter, 0) as string, out ft);
				universEdite.Dimmers[currDimm].fonctionTransfert = ft;
				MajListeDimmer();
			}
		}		

		protected void OnTxtParam1FocusOutEvent (object o, FocusOutEventArgs args)
		{
			if (majencour)
				return;
			float p1;
			if (float.TryParse (txtParam1.Text, out p1)) {
				universEdite.Dimmers [currDimm].param1 = p1;
				MajListeDimmer ();
			}
		}		

		protected void OnTxtParam2FocusOutEvent (object o, FocusOutEventArgs args)
		{
			if (majencour)
				return;
			float p2;
			if (float.TryParse (txtParam2.Text, out p2)) {
				universEdite.Dimmers [currDimm].param2 = p2;
				MajListeDimmer ();
			}
		}

		
		ListStore lsCircuits = new ListStore(typeof(Circuit));
		void ConstruitListeCircuits ()
		{

			var cirCol = new Gtk.TreeViewColumn();
			var cirCell = new Gtk.CellRendererText();
			cirCol.Title = "Circuit";
			cirCol.PackStart(cirCell,true);
			cirCol.SetCellDataFunc(cirCell, new Gtk.TreeCellDataFunc(	RenderCircuitsCol) );
			tvCircuits.AppendColumn(cirCol);

			var dimmCol = new Gtk.TreeViewColumn();
			var dimmCell = new Gtk.CellRendererText();
			dimmCol.Title = "Dimmers";
			dimmCol.PackEnd(dimmCell,true);
			dimmCol.SetCellDataFunc(dimmCell, new Gtk.TreeCellDataFunc(	RenderCircuitsDimmCol) );
			dimmCell.Editable = true;
			dimmCell.Edited += OnDimmerListEdited;
			tvCircuits.AppendColumn(dimmCol);

			tvCircuits.Model = lsCircuits;
			MajListeCircuits();
				
		}	

		void MajListeCircuits()
		{
			lsCircuits.Clear();
			foreach (Circuit c in Conduite.Courante.Circuits)
				lsCircuits.AppendValues(c);
		}		

		void RenderCircuitsCol (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{

			Circuit c = (Circuit)(tree_model.GetValue (iter, 0));
			(cell as Gtk.CellRendererText).Text = c.Name;

		}		

		void RenderCircuitsDimmCol (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
		{
			Circuit c = (Circuit)(tree_model.GetValue (iter, 0));
			List<string> dimmers = new List<string>();

			for (int i=0; i< universEdite.Dimmers.Length; i++) {
				if(universEdite.Dimmers[i].circuitAssocié == c)
					dimmers.Add(string.Format("{0} ",i +1));
			}

			(cell as Gtk.CellRendererText).Text = 
							string.Concat(dimmers);

		}		

		void OnDimmerListEdited (object o, EditedArgs args)
		{
			Gtk.TreeIter iter;
			lsCircuits.GetIter (out iter, new Gtk.TreePath (args.Path));
			Circuit c = lsCircuits.GetValue (iter, 0) as Circuit;

			string[] newdimlist = args.NewText.Split (' ','.');

			int val;

			for (int i=0; i< universEdite.Dimmers.Length; i++) {
				if(universEdite.Dimmers[i].circuitAssocié == c)
					universEdite.Dimmers[i].circuitAssocié= null;
			}

			foreach (string dim in newdimlist) {
				if(int.TryParse(dim, out val))
				{
					val--;
					if(val>=0 && val < universEdite.Dimmers.Length)
						universEdite.Dimmers[val].circuitAssocié = c;
				}
			}
			MajListeDimmer();
		}
	}
}
