/*******************************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All rights Reserved.
* 
* This software is protected by copyright laws of the United States and
* of foreign countries. This material may also be protected by patent laws
* and technology transfer regulations of the United States and of foreign
* countries. This software is furnished under a license agreement and/or a
* nondisclosure agreement and may only be used or reproduced in accordance
* with the terms of those agreements. Dissemination of this information to
* any party or parties not specified in the license agreement and/or
* nondisclosure agreement is expressly prohibited.
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HealthSensorPlatform.CustomControls;
using HealthSensorPlatform;


namespace HealthSensorPlatform
{
     // Code for ECG Input Mux Tab
    public partial class HspForm 
    {
        List<RegisterField> ecgInputMuxField = new List<RegisterField>();

        // Needed for dynamic changing of options
        RegisterField ecgCalFiftyField;


        public int[] sw = new int[15];

        void initalizeECGInputMuxFields()
        {
            string[] enDcloffOptions = { "Disabled*", "ECG Ch.", "BioZ Ch." };
            string[] dcloffIpolOptions = { "P: Pull Up, N: Pull Down*", "P: Pull Down, N: Pull Up" };
            string[] dcloffImagOptions = { "0nA/Disabled*", "5nA", "10nA", "20nA", "50nA", "100nA" };
            string[] dcloffVthOptions = { "VMID ±300mV*", "VMID ±400mV", "VMID ±450mV", "VMID ±500mV" };

            string[] enUlpLonOptions = { "Disabled", "ECG Ch.", "BioZ Ch." };

            string[] emuxOpenpOptions = { "Connected", "Isolated*" };
            string[] emuxOpennOptions = { "Connected", "Isolated*" };
            string[] emuxPolOptions = { "Non-Inverted*", "Inverted" };

            string[] enRbiasOptions = { "Disabled*", "ECG Bias", "BIOZ Bias" };
            string[] rBiasvOptions = { "50MΩ", "100MΩ*", "200MΩ" };
            string[] rBiaspOptions = { "Disconnected*", "Connected" };
            string[] rBiasnOptions = { "Disconnected*", "Connected" };

            string[] calEnVcalOptions = { "Disabled*", "Enabled" };
            string[] calVmodeOptions = { "Unipolar*", "Bipolar" };
            string[] calVmagOptions = { "0.25mV*", "0.50mV" };
            string[] calFcalOptions = { "FMSTR/128 (~256Hz)", "FMSTR/512 (~64Hz)", "FMSTR/2048 (~16Hz)", "FMSTR/8192 (~4Hz)", 
                                      "FMSTR/2^15 (~1Hz)*", "FMSTR/2^17 (~1/4Hz)",  "FMSTR/2^19 (~1/16Hz)", "FMSTR/2^21 (~1/64Hz)" };
            string[] calFiftyOptions = { "Time High", "50%*" };
            string[] calThighOptions = new string[2048/8]; // Assume FMSTR = 32768 Hz
            for (int i = 0; i < 2048/8; i++)
            {
                calThighOptions[i] = (30.52 * i * 8).ToString("F0") + " μs";
            }
            calThighOptions[0] += "*"; // Default

            string[] calPSelOptions = { "None*", "VMID", "VCALP", "VCALN" };
            string[] calNSelOptions = calPSelOptions;

            RegisterField enDcloffField = new RegisterField { Name = "\nEN_DCLOFF", Register = 0x10, Index = 12, Width = 2, Descriptions = enDcloffOptions, Label = lblEnDcloff, Control = cboEnDcloff , Device = max30001};
            RegisterField dcloffIpolField = new RegisterField { Name = "DCLOFF_IPOL", Register = 0x10, Index = 11, Width = 1, Descriptions = dcloffIpolOptions, Label = lblDcloffIpol, Control = cboDcloffIpol, Device = max30001 };
            RegisterField dcloffImagField = new RegisterField { Name = "DCLOFF_IMAG", Register = 0x10, Index = 8, Width = 3, Descriptions = dcloffImagOptions, Label = lblDcloffImag, Control = cboDcloffImag, Device = max30001 };
            RegisterField dcloffVthField = new RegisterField { Name = "DCLOFF_VTH", Register = 0x10, Index = 6, Width = 2, Descriptions = dcloffVthOptions, Label = lblDcloffVth, Control = cboDcloffVth, Device = max30001};
            ecgInputMuxField.Add(enDcloffField);
            ecgInputMuxField.Add(dcloffIpolField);
            ecgInputMuxField.Add(dcloffImagField);
            ecgInputMuxField.Add(dcloffVthField);

            RegisterField enUlpLonField = new RegisterField { Name = "\nEN_ULP_LON", Register = 0x10, Index = 22, Width = 2, Descriptions = enDcloffOptions, Label = lblEmuxEnUlpLon, Control =  cboEmuxEnUlpLon, Device = max30001};
            ecgInputMuxField.Add(enUlpLonField);


            RegisterField emuxOpenpField = new RegisterField { Name = "EMUX_OPENP", Register = 0x14, Index = 21, Width = 1, Descriptions = emuxOpenpOptions, Label = lblEmuxOpenp, Control = cboEmuxOpenp, Device = max30001 };
            RegisterField emuxOpennField = new RegisterField { Name = "EMUX_OPENN", Register = 0x14, Index = 20, Width = 1, Descriptions = emuxOpennOptions, Label = lblEmuxOpenn, Control = cboEmuxOpenn, Device = max30001 };
            RegisterField emuxPolField = new RegisterField { Name = "EMUX_POL", Register = 0x14, Index = 23, Width = 1, Descriptions = emuxPolOptions, Label = lblEmuxPol, Control = cboEmuxPol, Device = max30001 };
            ecgInputMuxField.Add(emuxOpenpField);
            ecgInputMuxField.Add(emuxOpennField);
            ecgInputMuxField.Add(emuxPolField);

            RegisterField enRbiasField = new RegisterField { Name = "\nEN_RBIAS", Register = 0x10, Index = 4, Width = 2, Descriptions = enDcloffOptions, Label = lblEnRbias, Control = cboEnRbias, Device = max30001 };
            RegisterField rBiasvField = new RegisterField { Name = "RBIASV", Register = 0x10, Index = 2, Width = 2, Descriptions = rBiasvOptions, Label = lblRbiasv, Control = cboRbiasv, Device = max30001 };
            RegisterField rBiaspField = new RegisterField { Name = "RBIASP", Register = 0x10, Index = 1, Width = 1, Descriptions = rBiaspOptions, Label = lblRbiasp, Control = cboRbiasp, Device = max30001 };
            RegisterField rBiasnField = new RegisterField { Name = "RBIASN", Register = 0x10, Index = 0, Width = 1, Descriptions = rBiasnOptions, Label = lblRbiasn, Control = cboRbiasn, Device = max30001 };
            ecgInputMuxField.Add(enRbiasField);
            ecgInputMuxField.Add(rBiasvField);
            ecgInputMuxField.Add(rBiaspField);
            ecgInputMuxField.Add(rBiasnField);

            RegisterField calEnVcalField = new RegisterField { Name = "CAL_EN_VCAL", Register = 0x12, Index = 22, Width = 1, Descriptions = calEnVcalOptions, Label = lblCalEnVcal, Control = cboCalEnVcal, Device = max30001 };
            RegisterField calVmodeField = new RegisterField { Name = "CAL_VMODE", Register = 0x12, Index = 21, Width = 1, Descriptions = calVmodeOptions, Label = lblCalVMode, Control = cboCalVmode, Device = max30001 };
            RegisterField calVmagField = new RegisterField { Name = "CAL_VMAG", Register = 0x12, Index = 20, Width = 1, Descriptions = calVmagOptions, Label = lblCalVmag, Control = cboCalVmag, Device = max30001 };
            RegisterField calFcalField = new RegisterField { Name = "CAL_FCAL", Register = 0x12, Index = 12, Width = 3, Descriptions = calFcalOptions, Label = lblCalFreq, Control = cboCalFcal, Device = max30001 };
            ecgCalFiftyField = new RegisterField { Name = "CAL_FIFTY", Register = 0x12, Index = 11, Width = 1, Descriptions = calFiftyOptions, Label = lblCalFifty, Control = cboCalFifty, Device = max30001 };
            RegisterField calThighField = new RegisterField { Name = "CAL_THIGH", Register = 0x12, Index = 3, Width = 8, Descriptions = calThighOptions, Label = lblCalTHigh, Control = cboCalThigh, Device = max30001 };
            // Decreasing GUI options from 2048 to 256 
            //RegisterField calThighField = new RegisterField { Name = "CAL_THIGH", Register = 0x12, Index = 0, Width = 10, Descriptions = calThighOptions, Label = lblCalTHigh };
            ecgInputMuxField.Add(calEnVcalField);
            ecgInputMuxField.Add(calVmodeField);
            ecgInputMuxField.Add(calVmagField);
            ecgInputMuxField.Add(calFcalField);
            ecgInputMuxField.Add(ecgCalFiftyField);
            ecgInputMuxField.Add(calThighField);

            RegisterField calPSelField = new RegisterField { Name = "EMUX_CALP_SEL", Register = 0x14, Index = 18, Width = 2, Descriptions = calPSelOptions, Label = lblEmuxCalPSel, Control = cboEmuxCalPSel, Device = max30001 };
            RegisterField calNSelField = new RegisterField { Name = "EMUX_CALN_SEL", Register = 0x14, Index = 16, Width = 2, Descriptions = calNSelOptions, Label = lblEmuxCalNSel, Control = cboEmuxCalNSel, Device = max30001 };
            ecgInputMuxField.Add(calPSelField);
            ecgInputMuxField.Add(calNSelField);
        }

        void ECGInputMuxUpdateRegisters()
        {
            internalUpdate = true;
            ReadComboBoxesRegisters(ecgInputMuxField);
            internalUpdate = false;
        }
        
        private void cboCalFifty_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboCalFifty.SelectedIndex == 1)
            {
                cboCalThigh.Enabled = false;
            }
            else
            {
                cboCalThigh.Enabled = true;
            }
        }

        private void cboEnDcloff_SelectedIndexChanged(object sender, EventArgs e)
        {
            MaximStyle.MaximComboBox cbo = (MaximStyle.MaximComboBox)sender;

            if (cbo.SelectedIndex == 0)
            {
                ecgView1.EnableDCLeadOff = false;
            }
            else
            {
                ecgView1.EnableDCLeadOff = true;
                if (cbo.SelectedIndex == 1)
                    ecgView1.EnableEcgDCLeadOff = true;
                else
                    ecgView1.EnableEcgDCLeadOff = false;
            }
            
            redrawEcgMuxImage();
        }

        private void cboDcloffIpol_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboEmuxEnUlpLon_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboEmuxOpenp_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboEmuxOpenn_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboEmuxPol_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboEnRbias_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboRbiasp_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboRbiasn_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboCalEnVcal_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboEmuxCalPSel_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void cboEmuxCalNSel_SelectedIndexChanged(object sender, EventArgs e)
        {
            redrawEcgMuxImage();
        }

        private void redrawEcgMuxImage()
        {
            processSwitchState();

            redrawSwitches();
        }

        private void processSwitchState()
        {
            //Logic for panel 1
            if (cboEnDcloff.SelectedIndex == 1)
            {
                if (cboDcloffIpol.SelectedIndex == 0)
                {
                    sw[1] = 0;
                    sw[2] = 1;
                    sw[10] = 1;
                    sw[11] = 0;
                }
                else
                {
                    sw[1] = 1;
                    sw[2] = 0;
                    sw[10] = 0;
                    sw[11] = 1;
                }
            }
            else
            {
                sw[1] = 0;
                sw[2] = 0;
                sw[10] = 0;
                sw[11] = 0;
            }
            //Logic for panel 2
            if (cboEmuxEnUlpLon.SelectedIndex == 1)
            {
                sw[3] = 1;
                sw[12] = 1;
            }
            else
            {
                sw[3] = 0;
                sw[12] = 0;
            }
            //Logic for panel 3
            if (cboEmuxPol.SelectedIndex == 0)
            {
                sw[7] = 0;
                sw[8] = 0;
                if (cboEmuxOpenp.SelectedIndex == 0)
                {
                    sw[6] = 1;
                }
                else
                {
                    sw[6] = 0;
                }
                if (cboEmuxOpenn.SelectedIndex == 0)
                {
                    sw[9] = 1;
                }
                else
                {
                    sw[9] = 0;
                }
            }
            else
            {
                sw[6] = 0;
                sw[9] = 0;
                if (cboEmuxOpenp.SelectedIndex == 0)
                {
                    sw[7] = 1;
                }
                else
                {
                    sw[7] = 0;
                }
                if (cboEmuxOpenn.SelectedIndex == 0)
                {
                    sw[8] = 1;
                }
                else
                {
                    sw[8] = 0;
                }
            }
            //Logic for panel 4
            if (cboEnRbias.SelectedIndex == 1)
            {
                if (cboRbiasp.SelectedIndex == 1)
                    sw[4] = 1;
                else
                    sw[4] = 0;
                if (cboRbiasn.SelectedIndex == 1)
                    sw[13] = 1;
                else
                    sw[13] = 0;
            }
            else
            {
                sw[4] = 0;
                sw[13] = 0;
            }
            //Logic 5
            if (cboCalEnVcal.SelectedIndex == 1)
            {
                if (cboEmuxCalPSel.SelectedIndex == 1 | cboEmuxCalPSel.SelectedIndex == 2 |
                    cboEmuxCalPSel.SelectedIndex == 3)
                    sw[5] = 1;
                else
                {
                    sw[5] = 0;
                }
                if (cboEmuxCalNSel.SelectedIndex == 1 | cboEmuxCalNSel.SelectedIndex == 2 |
                    cboEmuxCalNSel.SelectedIndex == 3)
                    sw[14] = 1;
                else
                {
                    sw[14] = 0;
                }
            }
            else
            {
                sw[5] = 0;
                sw[14] = 0;
            }
        }

        private void redrawSwitches()
        {
            // Dispose all Images
            if (picSw1.Image != null)
                picSw1.Image.Dispose();
            if (picSw2.Image != null)
                picSw2.Image.Dispose();
            if (picSw3.Image != null)
                picSw3.Image.Dispose();
            if (picSw4.Image != null)
                picSw4.Image.Dispose();
            if (picSw5.Image != null)
                picSw5.Image.Dispose();
            if (picSw6.Image != null)
                picSw6.Image.Dispose();
            if (picSw7.Image != null)
                picSw7.Image.Dispose();
            if (picSw8.Image != null)
                picSw8.Image.Dispose();
            if (picSw9.Image != null)
                picSw9.Image.Dispose();
            if (picSw10.Image != null)
                picSw10.Image.Dispose();
            if (picSw11.Image != null)
                picSw11.Image.Dispose();
            if (picSw12.Image != null)
                picSw12.Image.Dispose();
            if (picSw13.Image != null)
                picSw13.Image.Dispose();
            if (picSw14.Image != null)
                picSw14.Image.Dispose();

            if (sw[1] == 1)
                picSw1.Image = Properties.Resources.sw1;
            else
                picSw1.Image = null;
            if (sw[2] == 1)
                picSw2.Image = Properties.Resources.sw2;
            else
                picSw2.Image = null;
            if (sw[3] == 1)
                picSw3.Image = Properties.Resources.sw3;
            else
                picSw3.Image = null;
            if (sw[4] == 1)
                picSw4.Image = Properties.Resources.sw4;
            else
                picSw4.Image = null;
            if (sw[5] == 1)
                picSw5.Image = Properties.Resources.sw5;
            else
                picSw5.Image = null;
            if (sw[6] == 1)
                picSw6.Image = Properties.Resources.sw6;
            else
                picSw6.Image = null;
            if (sw[7] == 1)
                picSw7.Image = Properties.Resources.sw7;
            else
                picSw7.Image = null;
            if (sw[8] == 1)
                picSw8.Image = Properties.Resources.sw8;
            else
                picSw8.Image = null;
            if (sw[9] == 1)
                picSw9.Image = Properties.Resources.sw9;
            else
                picSw9.Image = null;
            if (sw[10] == 1)
                picSw10.Image = Properties.Resources.sw10;
            else
                picSw10.Image = null;
            if (sw[11] == 1)
                picSw11.Image = Properties.Resources.sw11;
            else
                picSw11.Image = null;
            if (sw[12] == 1)
                picSw12.Image = Properties.Resources.sw12;
            else
                picSw12.Image = null;
            if (sw[13] == 1)
                picSw13.Image = Properties.Resources.sw13;
            else
                picSw13.Image = null;
            if (sw[14] == 1)
                picSw14.Image = Properties.Resources.sw14;
            else
                picSw14.Image = null;
        }


        private InitArgs.EcgInitStart getEcgArgs()
        {
            InitArgs.EcgInitStart initArgs = new CustomControls.InitArgs.EcgInitStart();

            initArgs.Openp = cboEmuxOpenp.SelectedIndex;
            initArgs.Openn = cboEmuxOpenn.SelectedIndex;
            initArgs.Pol = cboEmuxPol.SelectedIndex;
            initArgs.Calp_sel = cboEmuxCalPSel.SelectedIndex;
            initArgs.Caln_sel = cboEmuxCalNSel.SelectedIndex;
            //initArgs.En_ecg = cboECGChannelEnable.SelectedIndex;
            initArgs.En_ecg = chkEnECG.Checked ? 1 : 0;
            initArgs.E_fit = 15;//0x1F; // TODO
            initArgs.Rate = cboSampleRate.SelectedIndex;
            initArgs.Gain = cboChannelGain.SelectedIndex;
            initArgs.Dhpf = cboDhpf.SelectedIndex;
            initArgs.Dlpf = cboDlpf.SelectedIndex;

            return initArgs;
        }

        private void setEcgArgs(InitArgs.EcgInitStart initArgs)
        {
            cboEmuxOpenp.SelectedIndex = initArgs.Openp;
            cboEmuxOpenn.SelectedIndex = initArgs.Openn;
            cboEmuxPol.SelectedIndex = initArgs.Pol;
            cboEmuxCalPSel.SelectedIndex = initArgs.Calp_sel;
            cboEmuxCalNSel.SelectedIndex = initArgs.Caln_sel;
            //initArgs.En_ecg = cboECGChannelEnable.SelectedIndex;
            //initArgs.En_ecg = chkEnECG.Checked == true ? 1 : 0;
            //initArgs.E_fit = 15;//0x1F; 
            cboSampleRate.SelectedIndex = initArgs.Rate;
            cboChannelGain.SelectedIndex = initArgs.Gain;
            cboDhpf.SelectedIndex = initArgs.Dhpf;
            cboDlpf.SelectedIndex = initArgs.Dlpf;
        }

        private InitArgs.FMSTRInitStart getFMSTRArgs()
        {
            InitArgs.FMSTRInitStart initArgs = new InitArgs.FMSTRInitStart();

            initArgs.En_rbias = cboEnRbias.SelectedIndex;
            initArgs.Rbiasv = cboRbiasv.SelectedIndex;
            initArgs.Rbiasp = cboRbiasp.SelectedIndex;
            initArgs.Rbiasn = cboRbiasn.SelectedIndex;
            initArgs.Fmstr = cboMasterClock.SelectedIndex;

            return initArgs;
        }

        private void setFMSTRArgs(InitArgs.FMSTRInitStart initArgs)
        {
            cboEnRbias.SelectedIndex = initArgs.En_rbias;
            cboRbiasv.SelectedIndex = initArgs.Rbiasv;
            cboRbiasp.SelectedIndex = initArgs.Rbiasp;
            cboRbiasn.SelectedIndex = initArgs.Rbiasn;
            cboMasterClock.SelectedIndex = initArgs.Fmstr;
        }

    }
}
