// !! 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;
using System.IO;						// for file I/O
using System.Runtime.InteropServices;	// so we can marshal our structures in drpf.cs

namespace drpfTest
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.TextBox drpfFile;
		private System.Windows.Forms.Button updatecode;
		private System.Windows.Forms.Button updatecodeMod;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public string AppName = "drpfTest";

		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 );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.label1 = new System.Windows.Forms.Label();
			this.drpfFile = new System.Windows.Forms.TextBox();
			this.updatecode = new System.Windows.Forms.Button();
			this.updatecodeMod = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(16, 24);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(440, 16);
			this.label1.TabIndex = 0;
			this.label1.Text = "Full path of drpf file:";
			// 
			// drpfFile
			// 
			this.drpfFile.Location = new System.Drawing.Point(16, 40);
			this.drpfFile.Name = "drpfFile";
			this.drpfFile.Size = new System.Drawing.Size(424, 20);
			this.drpfFile.TabIndex = 1;
			this.drpfFile.Text = "";
			// 
			// updatecode
			// 
			this.updatecode.Location = new System.Drawing.Point(96, 88);
			this.updatecode.Name = "updatecode";
			this.updatecode.Size = new System.Drawing.Size(264, 23);
			this.updatecode.TabIndex = 2;
			this.updatecode.Text = "Generate Update Code";
			this.updatecode.Click += new System.EventHandler(this.updatecode_Click);
			// 
			// updatecodeMod
			// 
			this.updatecodeMod.Location = new System.Drawing.Point(96, 128);
			this.updatecodeMod.Name = "updatecodeMod";
			this.updatecodeMod.Size = new System.Drawing.Size(264, 23);
			this.updatecodeMod.TabIndex = 3;
			this.updatecodeMod.Text = "Generate Update Code with modifications ";
			this.updatecodeMod.Click += new System.EventHandler(this.updatecodeMod_Click);
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(456, 174);
			this.Controls.Add(this.updatecodeMod);
			this.Controls.Add(this.updatecode);
			this.Controls.Add(this.drpfFile);
			this.Controls.Add(this.label1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);

		}
		#endregion

		/* The sample code contains 2 functions. Use which ever functions are most appropriate and customise
        in your own way. The sample code is just a guide.  
        
        There are two methods to loading a DRPF file. These are shown in the these two functions
        updatecode_Click and updatecodeMod_Click:
        
        updatecode_Click: we load the DRPF file from disk and get a handle and use it "as is" using the API
                          call LoadDRPFFromFile. You can make some limited changes to overwrite the default
                          behaviour by using API flags.
                             
        updatecodeMod_Click: we load the DRPF file from disk and load into structures. We can then modify the
                             DRPF settings by modifying this structure. This method uses the API calls
                             ReadDRPFEx and LoadDRPF.
                                
        */

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

		private void updatecode_Click(object sender, System.EventArgs e)
		{
			IntPtr drpfHandle;
			int err_code;
            UPDATE_CODE_OUTPUTS Outputs = new UPDATE_CODE_OUTPUTS();
            
			// load DRPF from File into memory
			drpfHandle = DinkeyRemote.LoadDRPFFromFile(drpfFile.Text, out err_code);
			if (drpfHandle == IntPtr.Zero)
			{
				MessageBox.Show(DinkeyRemote.GetLastMessage(), AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}

			// generate update code as specified by the DRPF file
			err_code = DinkeyRemote.GenerateUpdateCode(drpfHandle, 0, 0, null, null, out Outputs);

			// Unload DRPF from memory
			DinkeyRemote.UnloadDRPF(ref drpfHandle);

			// display message (error or success)
			MessageBox.Show(DinkeyRemote.GetLastMessage(), AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
				
		}

		private void updatecodeMod_Click(object sender, System.EventArgs e)
		{
			IntPtr drpfHandle;
			int dummy1, dummy2, err_code;
			REMOTEINFO RemoteInfo;
			LICENCEINFO[] LicenceInfo;
			ALGCHANGE[] AlgChanges;
			DATACHANGE[] DataChanges;
			UPDATE_CODE_OUTPUTS Outputs = new UPDATE_CODE_OUTPUTS();

			// in this case we need to read the DRPF into our structures, so that the DRPF values can be modified
			err_code = DinkeyRemote.ReadDRPFEx(drpfFile.Text, out RemoteInfo, out LicenceInfo, out AlgChanges, out DataChanges, out dummy1, out dummy2);
			if (err_code != 0)
			{
				MessageBox.Show(DinkeyRemote.GetLastMessage(), AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}

			// patch new values in the RemoteInfo, LicenceInfo, AlgChanges, DataChanges structures
			LicenceInfo[0].FeaturesFlag = 1;                        // so that the features value below will be recognised
			LicenceInfo[0].Features = 12345;
			LicenceInfo[0].AddSetExecs = 1;                         // so the executions will be added to existing
			LicenceInfo[0].Execs = 100;

			// get DRPF handle
			drpfHandle = DinkeyRemote.LoadDRPF(RemoteInfo, LicenceInfo, AlgChanges, DataChanges, out err_code);
			if (drpfHandle == IntPtr.Zero)
			{
				MessageBox.Show(DinkeyRemote.GetLastMessage(), AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}

			// generate update code as specified by the modified DRPF file
			err_code = DinkeyRemote.GenerateUpdateCode(drpfHandle, 0, 0, null, null, out Outputs);

			// Unload DRPF from memory
			DinkeyRemote.UnloadDRPF(ref drpfHandle);

			// display message (error or success)
			MessageBox.Show(DinkeyRemote.GetLastMessage(), AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
			return;		
		}

	}
}
