// !! We strongly recommend that you read the "readme.txt" file in the sample code folder.
// !! It contains important instructions on how to use the sample code

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace ChangeTest
{

    /// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Button get_dongle_info;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.TextBox diag_filename;
		private System.Windows.Forms.Button write_diag_file;
		private System.Windows.Forms.Button do_update_code_string;
		private System.Windows.Forms.TextBox update_code_string;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Button do_update_code_file;
		private System.Windows.Forms.TextBox update_code_file;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Button restore_fd_lite;
		private System.Windows.Forms.Button get_machine_id;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.TextBox swkey_prod_code;
		private System.Windows.Forms.Button download_temp_swkey;
		private System.Windows.Forms.Button download_demo_swkey;
		private System.Windows.Forms.TextBox machine_id;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

        public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		// maximum number of USB devices that can be attached to a machine at any time
		public const int MAX_USB_DEVICES = 128;
		public const int MAX_PRODCODE_LEN = 9;			// including terminating null

		public string AppName = "ChangeTest";

		// mask values
		public const int TYPE_MASK_PRO = 1;
		public const int TYPE_MASK_FD = 2;
		public const int TYPE_MASK_ALL = (TYPE_MASK_PRO | TYPE_MASK_FD);
		
		public const int MODEL_MASK_LITE = 1;
		public const int MODEL_MASK_PLUS = 2;
		public const int MODEL_MASK_NET = 4;
		public const int MODEL_MASK_ALL	= (MODEL_MASK_LITE | MODEL_MASK_PLUS | MODEL_MASK_NET);
		public const int MODEL_MASK_DEFAULT	= (MODEL_MASK_PLUS | MODEL_MASK_NET);

		// type values for DCGetInfo (returned in the array)
		public const int TYPE_PRO = 1;
		public const int TYPE_FD = 2;

		// model values for DCGetInfo (returned in the array)
		public const int MODEL_LITE = 1;
		public const int MODEL_PLUS = 2;
		public const int MODEL_NET5	= 4;
		public const int MODEL_NETU = 7;     

		// model values for DCDownloadDemoSoftwareKey
		public const int SWKEY_MODEL_DEFAULT  = -1;            // NB this assumes that the Demo Software Key Template was created with only one valid dongle model
		public const int SWKEY_MODEL_PRO_LITE = 0;
		public const int SWKEY_MODEL_PRO_PLUS = 1;
		public const int SWKEY_MODEL_PRO_NET  = 2;
		public const int SWKEY_MODEL_FD_LITE  = 3;
		public const int SWKEY_MODEL_FD_PLUS  = 4;
		public const int SWKEY_MODEL_FD_NET   = 5;

		private void InitializeComponent()
		{
			this.get_dongle_info = new System.Windows.Forms.Button();
			this.label1 = new System.Windows.Forms.Label();
			this.diag_filename = new System.Windows.Forms.TextBox();
			this.write_diag_file = new System.Windows.Forms.Button();
			this.do_update_code_string = new System.Windows.Forms.Button();
			this.update_code_string = new System.Windows.Forms.TextBox();
			this.label2 = new System.Windows.Forms.Label();
			this.do_update_code_file = new System.Windows.Forms.Button();
			this.update_code_file = new System.Windows.Forms.TextBox();
			this.label3 = new System.Windows.Forms.Label();
			this.restore_fd_lite = new System.Windows.Forms.Button();
			this.get_machine_id = new System.Windows.Forms.Button();
			this.machine_id = new System.Windows.Forms.TextBox();
			this.download_temp_swkey = new System.Windows.Forms.Button();
			this.label4 = new System.Windows.Forms.Label();
			this.swkey_prod_code = new System.Windows.Forms.TextBox();
			this.download_demo_swkey = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// get_dongle_info
			// 
			this.get_dongle_info.Location = new System.Drawing.Point(48, 24);
			this.get_dongle_info.Name = "get_dongle_info";
			this.get_dongle_info.Size = new System.Drawing.Size(224, 24);
			this.get_dongle_info.TabIndex = 0;
			this.get_dongle_info.Text = "Get Dongle Information";
			this.get_dongle_info.Click += new System.EventHandler(this.get_dongle_info_Click);
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(16, 72);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(280, 16);
			this.label1.TabIndex = 1;
			this.label1.Text = "Enter diagnostic filename:";
			// 
			// diag_filename
			// 
			this.diag_filename.Location = new System.Drawing.Point(16, 88);
			this.diag_filename.Name = "diag_filename";
			this.diag_filename.Size = new System.Drawing.Size(288, 20);
			this.diag_filename.TabIndex = 2;
			this.diag_filename.Text = "";
			// 
			// write_diag_file
			// 
			this.write_diag_file.Location = new System.Drawing.Point(48, 120);
			this.write_diag_file.Name = "write_diag_file";
			this.write_diag_file.Size = new System.Drawing.Size(224, 24);
			this.write_diag_file.TabIndex = 3;
			this.write_diag_file.Text = "Write Diagnostics to File";
			this.write_diag_file.Click += new System.EventHandler(this.write_diag_file_Click);
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(16, 168);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(280, 16);
			this.label2.TabIndex = 4;
			this.label2.Text = "Enter short Update Code here:";
			// 
			// update_code_string
			// 
			this.update_code_string.Location = new System.Drawing.Point(16, 184);
			this.update_code_string.Name = "update_code_string";
			this.update_code_string.Size = new System.Drawing.Size(288, 20);
			this.update_code_string.TabIndex = 5;
			this.update_code_string.Text = "";
			// 
			// do_update_code_string
			// 
			this.do_update_code_string.Location = new System.Drawing.Point(48, 216);
			this.do_update_code_string.Name = "do_update_code_string";
			this.do_update_code_string.Size = new System.Drawing.Size(224, 24);
			this.do_update_code_string.TabIndex = 6;
			this.do_update_code_string.Text = "Make Changes";
			this.do_update_code_string.Click += new System.EventHandler(this.do_update_code_string_Click);
			// 
			// do_update_code_file
			// 
			this.do_update_code_file.Location = new System.Drawing.Point(48, 312);
			this.do_update_code_file.Name = "do_update_code_file";
			this.do_update_code_file.Size = new System.Drawing.Size(224, 24);
			this.do_update_code_file.TabIndex = 9;
			this.do_update_code_file.Text = "Make Changes";
			this.do_update_code_file.Click += new System.EventHandler(this.do_update_code_file_Click);
			// 
			// update_code_file
			// 
			this.update_code_file.Location = new System.Drawing.Point(16, 280);
			this.update_code_file.Name = "update_code_file";
			this.update_code_file.Size = new System.Drawing.Size(288, 20);
			this.update_code_file.TabIndex = 8;
			this.update_code_file.Text = "";
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(16, 264);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(280, 16);
			this.label3.TabIndex = 7;
			this.label3.Text = "Enter path to Update Code file:";
			// 
			// restore_fd_lite
			// 
			this.restore_fd_lite.Location = new System.Drawing.Point(48, 368);
			this.restore_fd_lite.Name = "restore_fd_lite";
			this.restore_fd_lite.Size = new System.Drawing.Size(224, 24);
			this.restore_fd_lite.TabIndex = 10;
			this.restore_fd_lite.Text = "Restore Dinkey FD Lite";
			this.restore_fd_lite.Click += new System.EventHandler(this.restore_fd_lite_Click);
			// 
			// get_machine_id
			// 
			this.get_machine_id.Location = new System.Drawing.Point(16, 424);
			this.get_machine_id.Name = "get_machine_id";
			this.get_machine_id.Size = new System.Drawing.Size(144, 24);
			this.get_machine_id.TabIndex = 11;
			this.get_machine_id.Text = "Get Machine ID";
			this.get_machine_id.Click += new System.EventHandler(this.get_machine_id_Click);
			// 
			// machine_id
			// 
			this.machine_id.Location = new System.Drawing.Point(168, 424);
			this.machine_id.Name = "machine_id";
			this.machine_id.Size = new System.Drawing.Size(136, 20);
			this.machine_id.TabIndex = 12;
			this.machine_id.Text = "";
			// 
			// download_temp_swkey
			// 
			this.download_temp_swkey.Location = new System.Drawing.Point(48, 480);
			this.download_temp_swkey.Name = "download_temp_swkey";
			this.download_temp_swkey.Size = new System.Drawing.Size(224, 24);
			this.download_temp_swkey.TabIndex = 13;
			this.download_temp_swkey.Text = "Download Temporary Software Key";
			this.download_temp_swkey.Click += new System.EventHandler(this.download_temp_swkey_Click);
			// 
			// label4
			// 
			this.label4.Location = new System.Drawing.Point(16, 528);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(280, 16);
			this.label4.TabIndex = 14;
			this.label4.Text = "Demo Software Key Product Code:";
			// 
			// swkey_prod_code
			// 
			this.swkey_prod_code.Location = new System.Drawing.Point(16, 544);
			this.swkey_prod_code.Name = "swkey_prod_code";
			this.swkey_prod_code.Size = new System.Drawing.Size(288, 20);
			this.swkey_prod_code.TabIndex = 15;
			this.swkey_prod_code.Text = "";
			// 
			// download_demo_swkey
			// 
			this.download_demo_swkey.Location = new System.Drawing.Point(48, 576);
			this.download_demo_swkey.Name = "download_demo_swkey";
			this.download_demo_swkey.Size = new System.Drawing.Size(224, 24);
			this.download_demo_swkey.TabIndex = 16;
			this.download_demo_swkey.Text = "Download Demo Software Key";
			this.download_demo_swkey.Click += new System.EventHandler(this.download_demo_swkey_Click);
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(320, 624);
			this.Controls.Add(this.download_demo_swkey);
			this.Controls.Add(this.swkey_prod_code);
			this.Controls.Add(this.label4);			
            this.Controls.Add(this.machine_id);
			this.Controls.Add(this.download_temp_swkey);
			this.Controls.Add(this.get_machine_id);
			this.Controls.Add(this.restore_fd_lite);
			this.Controls.Add(this.do_update_code_file);
			this.Controls.Add(this.update_code_file);
			this.Controls.Add(this.label3);
			this.Controls.Add(this.do_update_code_string);
			this.Controls.Add(this.update_code_string);
			this.Controls.Add(this.label2);
			this.Controls.Add(this.write_diag_file);
			this.Controls.Add(this.diag_filename);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.get_dongle_info);
			this.Name = "Form1";
			this.Text = "ChangeTest";
			this.ResumeLayout(false);

		}

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		// routine to get & display information for all dongles attached
		private void get_dongle_info_Click(object sender, System.EventArgs e)
		{
			int ret_code, i, num_found;
			string DisplayString = null;
			string Type, Model, ProdCodeString;
			// return arrays of dongle details filedin by DCGetInfo
			int[] type = new int[MAX_USB_DEVICES];
			int[] model = new int[MAX_USB_DEVICES];
			byte[] prodcode = new Byte[MAX_USB_DEVICES*MAX_PRODCODE_LEN];
			uint[] dongle_number = new uint[MAX_USB_DEVICES];
			int[] update_number = new int[MAX_USB_DEVICES];

			// find dongle information for all dongle types, Plus & Net models, for all product codes
			// NB In practice you will probably want to set the prodcode_mask to the value of your product code			
			ret_code = DinkeyChange.DCGetInfo(TYPE_MASK_ALL, MODEL_MASK_DEFAULT, null, MAX_USB_DEVICES, out num_found, type, model, prodcode, dongle_number, update_number);

			// check error code and display error if an error occurs
			if (ret_code == 401) 
			{
				MessageBox.Show("No dongles detected matching the search criteria specified", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			else if (ret_code != 0) 
			{
				DisplayString = "An error occurred getting dongle information. Error: " + String.Format("{0:D}", ret_code);
				MessageBox.Show(DisplayString, AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
				
			// display info for dongle(s) detected
			for (i=0; i<num_found; i++) 
			{
				// get type of dongle
				if (type[i] == TYPE_PRO)
					Type = "Pro";
				else
					Type = "FD";
					
				// get model of dongle
				if (model[i] == MODEL_LITE)
					Model = "Lite";
				else if (model[i] == MODEL_PLUS)
					Model = "Plus";
				else
					Model = "Net";
				
				ProdCodeString = DinkeyChange.GetProductCode(prodcode, i);

				DisplayString += String.Format("{0}. Dinkey {1} {2} with dongle number: {3}, product code: {4}, update number: {5}", i+1, Type, Model, dongle_number[i], ProdCodeString, update_number[i]);
				DisplayString += Environment.NewLine;
			}
			MessageBox.Show(DisplayString, "Dongle Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
			return;
		}

		// Write Dongle Diagnostics to file
		private void write_diag_file_Click(object sender, System.EventArgs e)
		{
			int ret_code;

			// NB this could take a while if the data area is very large
			ret_code = DinkeyChange.DCGetDiagnosticInfo(diag_filename.Text);

			// check error code and display error if an error occurs
			if (ret_code == 754) 
			{
				MessageBox.Show("Could not create the diagnostic file. Please check that the path exists: " + diag_filename.Text, AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			else if (ret_code != 0) 
			{
				MessageBox.Show(String.Format("Error {0} writing diagnostic information", ret_code), AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			// display success
			MessageBox.Show("Diagnostic file written successfully.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
			return;
		}

		// Update dongle using short code typed-in
		private void do_update_code_string_Click(object sender, System.EventArgs e)
		{
			int ret_code, confirmation_code, extended_error;
				
			// make changes
			ret_code = DinkeyChange.DCDoUpdateCodeString(update_code_string.Text, out confirmation_code, out extended_error);

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, extended_error);
				return;
			}
			MessageBox.Show(String.Format("Dongle updated successfully!\nConfirmation code is : {0:X4}", confirmation_code), AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		private void do_update_code_file_Click(object sender, System.EventArgs e)
		{
			int ret_code, confirmation_code, extended_error;
				
			// make changes
			ret_code = DinkeyChange.DCDoUpdateCodeFromFile(update_code_file.Text,  out confirmation_code, out extended_error);

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, extended_error);
				return;
			}
			MessageBox.Show(String.Format("Dongle updated successfully!\nConfirmation code is : {0:X4}", confirmation_code), AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		// attempt to restore a Dinkey FD Lite dongle
		private void restore_fd_lite_Click(object sender, System.EventArgs e)
		{
			int ret_code;
	
			ret_code = DinkeyChange.DCRestoreDinkeyFDLite();

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, 0);
				return;
			}
			MessageBox.Show("Dinkey FD Lite restored successfully.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		private void get_machine_id_Click(object sender, System.EventArgs e)
		{
			int ret_code, extended_error;
			uint machineID;
	
			ret_code = DinkeyChange.DCGetMachineID(out machineID, out extended_error);

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, extended_error);
				return;
			}
			// display the machine ID in the text box
			machine_id.Text = String.Format("{0:X8}", machineID);
		}

		private void download_temp_swkey_Click(object sender, System.EventArgs e)
		{
			int ret_code, extended_error;
			uint machineID;

			// first get the machine ID...
			ret_code = DinkeyChange.DCGetMachineID(out machineID, out extended_error);

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, extended_error);
				return;
			}
			
			// ... and then try to download the temporary software key
			ret_code = DinkeyChange.DCDownloadTempSoftwareKey(machineID, out extended_error);

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, extended_error);
				return;
			}
			MessageBox.Show("Temporary Software Key downloaded successfully.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		private void download_demo_swkey_Click(object sender, System.EventArgs e)
		{
			int ret_code, extended_error;
			uint machineID;

			// first get the machine ID...
			ret_code = DinkeyChange.DCGetMachineID(out machineID, out extended_error);

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, extended_error);
				return;
			}
			
			// try to download the demo software key
			// (NB we are assuming only one dongle model is set in the Demo Software Template.
			//  If multiple models are set you will also need to specify the exact model)
			ret_code = DinkeyChange.DCDownloadDemoSoftwareKey(machineID, swkey_prod_code.Text, SWKEY_MODEL_DEFAULT, out extended_error);

			// check error code and display error if an error occurs
			if (ret_code != 0) 
			{
				DisplayError(ret_code, extended_error);
				return;
			}
			MessageBox.Show("Demo Software Key downloaded successfully.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		// displays messages for the most common errors. You will want to change this for your code
		void DisplayError(int ret_code, int extended_error) 
		{
			switch (ret_code) 
			{
				case 401:
					MessageBox.Show("Error! No dongles detected that meet the search criteria!", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					break;
	
				case 409:
					MessageBox.Show("Error! The dongle detected has not been programmed by DinkeyAdd.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					break;

				case 758:
					MessageBox.Show("Error! Cannot open the Update Code file specified.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					break;

				case 759:
					MessageBox.Show("Error! The file specified is not a valid Update Code file.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					break;

				case 762:
				case 763:
				case 764:
					MessageBox.Show("Error! Update Code is not in a correct format / update code file is corrupt.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 765:
					MessageBox.Show("Error! The Update Code does not match any dongle attached to your machine.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 766:
					MessageBox.Show("Error! The update number for this Update Code is too high. You need to first enter an update code that was previously sent to you.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 767:
					MessageBox.Show("Error! You have already entered this Update Code.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 1905:
					MessageBox.Show("Error! There is no Software Key available for download.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 1907:
					MessageBox.Show("Error! The Temporary Software Key has expired. Cannot download it.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 1910:
					MessageBox.Show("Error! The Software Key has already been downloaded.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 1921:
					MessageBox.Show("Error! You specified the 'default model' but there is more than one model available. You need to specify a specific dongle model.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 1922:
					MessageBox.Show("Error! The model you requested is not available.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 1923:
					MessageBox.Show("Error! The Demo Software Key Template has been disabled.", AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
					break;

				case 1924:
					MessageBox(NULL, "Error! You have run out of Demo Software Key activations. You need to order some more.", g_szAppName, MB_OK); 
					break;

				default:
					MessageBox.Show(String.Format("An error occurred updating the dongle.\nError: {0}, Extended Error: {1}", ret_code, extended_error), AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					break;
			}
			return;
		}
	}
}
