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

using i8196F;

namespace MultiaxisMotion
{
    public partial class Form1 : Form
    {
        byte bSlotNo;

        public Form1()
        {
            InitializeComponent();

            cmbARCAxisX.SelectedIndex = 0;
            cmbARCAxisY.SelectedIndex = 1;

            cmbHelicalAxis0.SelectedIndex = 0;
            cmbHelicalAxis1.SelectedIndex = 1;
            cmbHelicalAxis2.SelectedIndex = 2;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            short ret = 0;
            byte i = 0;

            bool flgExistCard = false;

            for (i = 0; i < 9; i++)
            {
                ret = C96F.i8196f_check_card_in_slot(i);
                if (ret == 0)
                {
                    InitialI8196F(i);
                    cmbSlotNo.Items.Add(i.ToString());
                    flgExistCard = true;
                }
            }

            if (flgExistCard)
            {
                cmbSlotNo.SelectedIndex = 0;
                bSlotNo = System.Byte.Parse(cmbSlotNo.Text);
                timer1.Enabled = true;
            }
            else
            {
                MessageBox.Show("No I-8196F!");
                timer1.Enabled = false;
            }          
        }

        private void InitialI8196F(byte SlotNo)
        {
            short ret;

            int i = 0;

            byte AxisNo;

            ret = C96F.i8196f_registration(SlotNo);

            ret = C96F.i8196f_load_power_on_cfg(SlotNo, ePOWER_ON_SETTING.DEFAULT_POWER_ON_SETTING);

            for (i = 0; i < 6; i++)
            {
                AxisNo = (byte)(0x01 << i);

                ret = C96F.i8196f_set_pls_cfg(SlotNo, (eSINGLE_AXIS)AxisNo, ePULSE_MODE.PULSE_MODE_CW_CCW,
                                        ePULSE_LOGIC.PULSE_LOGIC_ACTIVE_HIGH, eFORWARD_ACTIVE.PULSE_FORWARD_ACTIVE_HIGH);
                ret = C96F.i8196f_set_enc_cfg(SlotNo, (eSINGLE_AXIS)AxisNo, eENCODER_MODE.ENCODER_MODE_CW_CCW);
                ret = C96F.i8196f_set_limit(SlotNo, (eSINGLE_AXIS)AxisNo, eLOGIC_ACTIVE_LEVEL.LOGIC_ACTIVE_LOW, eSTOP_MODE.STOP_SUDDEN);
                ret = C96F.i8196f_set_alarm(SlotNo, (eSINGLE_AXIS)AxisNo, eENABLE_DISABLE.DISABLE, eLOGIC_ACTIVE_LEVEL.LOGIC_ACTIVE_LOW);
                ret = C96F.i8196f_set_inp(SlotNo, (eSINGLE_AXIS)AxisNo, eENABLE_DISABLE.DISABLE, eLOGIC_ACTIVE_LEVEL.LOGIC_ACTIVE_LOW);
                ret = C96F.i8196f_set_ready(SlotNo, (eSINGLE_AXIS)AxisNo, eENABLE_DISABLE.DISABLE, eLOGIC_ACTIVE_LEVEL.LOGIC_ACTIVE_LOW);
            }
        }

        private void cmbSlotNo_SelectedIndexChanged(object sender, EventArgs e)
        {
            bSlotNo = System.Byte.Parse(cmbSlotNo.Text);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            TextBox[] txtGetIOSts = { txtGetIOSts0, txtGetIOSts1, txtGetIOSts2, txtGetIOSts3, txtGetIOSts4, txtGetIOSts5 };
            TextBox[] txtGetCMD = { txtGetCMD0, txtGetCMD1, txtGetCMD2, txtGetCMD3, txtGetCMD4, txtGetCMD5 };
            TextBox[] txtGetENC = { txtGetENC0, txtGetENC1, txtGetENC2, txtGetENC3, txtGetENC4, txtGetENC5 };
            TextBox[] txtGetSpd = { txtGetSpd0, txtGetSpd1, txtGetSpd2, txtGetSpd3, txtGetSpd4, txtGetSpd5 };
            TextBox[] txtGetMCsts = { txtGetMCsts0, txtGetMCsts1, txtGetMCsts2, txtGetMCsts3, txtGetMCsts4, txtGetMCsts5 };

            short ret = 0;
            int i = 0;
            byte AxisNo = 0;
            ushort wDIStatus = 0;
            int LP = 0, EP = 0, Spd = 0;
            byte bDone = 0;
            ushort wStopStatus = 0;

            for (i = 0; i < 6; i++)
            {

                AxisNo = (byte)(0x01 << i);

                ret = C96F.i8196f_get_mdi_status(bSlotNo, (eSINGLE_AXIS)AxisNo, ref wDIStatus);
                txtGetIOSts[i].Text = "0x" + wDIStatus.ToString("X4");

                ret = C96F.i8196f_get_cmdcounter(bSlotNo, (eSINGLE_AXIS)AxisNo, ref LP);
                txtGetCMD[i].Text = LP.ToString();

                ret = C96F.i8196f_get_enccounter(bSlotNo, (eSINGLE_AXIS)AxisNo, ref EP);
                txtGetENC[i].Text = EP.ToString();

                ret = C96F.i8196f_get_speed(bSlotNo, (eSINGLE_AXIS)AxisNo, ref Spd);
                txtGetSpd[i].Text = Spd.ToString();

                ret = C96F.i8196f_get_motion_done(bSlotNo, (eSINGLE_AXIS)AxisNo, ref bDone, ref wStopStatus);
                txtGetMCsts[i].Text = "(" + bDone.ToString() + ")" + wStopStatus.ToString("X4");

            }
        }

        private void ResetCnt(object sender, EventArgs e)
        {
            int index = int.Parse((sender as Button).Tag.ToString());

            int i = 0;
            short ret = 0;
            byte AxisNo = 0;
            int LogicPos = 0;
            int EncPos = 0;

            if (index < 6)
            {
                AxisNo = (byte)(0x01 << index);
                ret = C96F.i8196f_set_cmdcounter(bSlotNo, (eSINGLE_AXIS)AxisNo, LogicPos);
                ret = C96F.i8196f_set_enccounter(bSlotNo, (eSINGLE_AXIS)AxisNo, EncPos);
            }
            else if (index == 6)
            {
                for (i = 0; i < 6; i++)
                {
                    AxisNo = (byte)(0x01 << i);
                    ret = C96F.i8196f_set_cmdcounter(bSlotNo, (eSINGLE_AXIS)AxisNo, LogicPos);
                    ret = C96F.i8196f_set_enccounter(bSlotNo, (eSINGLE_AXIS)AxisNo, EncPos);
                }
            }
        }

        private void ToggleSVON(object sender, EventArgs e)
        {
            int index = int.Parse((sender as Control).Tag.ToString());

            byte AxisNo = (byte)(0x01 << index);
            short ret = 0;
            eCHANNEL_STATE OnOff = 0;

            ret = C96F.i8196f_get_servo_on_status(bSlotNo, (eSINGLE_AXIS)AxisNo, ref OnOff);
            if (OnOff == eCHANNEL_STATE.OFF)
            { ret = C96F.i8196f_set_servo_on(bSlotNo, (eSINGLE_AXIS)AxisNo, eCHANNEL_STATE.ON); }
            else
            { ret = C96F.i8196f_set_servo_on(bSlotNo, (eSINGLE_AXIS)AxisNo, eCHANNEL_STATE.OFF); }
        }

        private void ToggleRALM(object sender, EventArgs e)
        {
            int index = int.Parse((sender as Control).Tag.ToString());

            byte AxisNo = (byte)(0x01 << index);
            short ret = 0;
            eCHANNEL_STATE OnOff = 0;

            ret = C96F.i8196f_get_servo_almrst_status(bSlotNo, (eSINGLE_AXIS)AxisNo, ref OnOff);
            if (OnOff == eCHANNEL_STATE.OFF)
            { ret = C96F.i8196f_set_alarm_reset(bSlotNo, (eSINGLE_AXIS)AxisNo, eCHANNEL_STATE.ON); }
            else
            { ret = C96F.i8196f_set_alarm_reset(bSlotNo, (eSINGLE_AXIS)AxisNo, eCHANNEL_STATE.OFF); }
        }

        private void btnLineMove_Click(object sender, EventArgs e)
        {
            CheckBox[] chkAxis = { chkAxis0, chkAxis1, chkAxis2, chkAxis3, chkAxis4, chkAxis5 };
            TextBox[] edtDist = { txtDist0, txtDist1, txtDist2, txtDist3, txtDist4, txtDist5 };

            short ret = 0;
            int i = 0;
            byte[] ArrAxis = new byte[6];
            int AxisCnt = 0;
            int[] ArrDist = new int[6];
            uint Speed = System.UInt32.Parse(txtLineSpeed.Text);
            uint Acc = System.UInt32.Parse(txtLineAcc.Text);

            eINTERPOLATION_MODE eInterpMode = eINTERPOLATION_MODE.GENERAL_INTERP_CONFIG;

            int[] FixedPulse = new int[6];

            byte bitAxis = 0;

            for (i = 0; i < 6; i++)
            {
                if (chkAxis[i].Checked)
                {
                    ArrAxis[AxisCnt] = (byte)(0x01 << i);
                    ArrDist[AxisCnt] = System.Int32.Parse(edtDist[i].Text);
                    FixedPulse[i] = System.Int32.Parse(edtDist[i].Text);
                    bitAxis |= ArrAxis[AxisCnt];
                    AxisCnt++;
                }
            }

            if (rdoR.Checked)
            {
                switch (AxisCnt)
                {
                    case 0:
                        break;
                    case 1:
                        ret = C96F.i8196f_t_move(bSlotNo, (eSINGLE_AXIS)ArrAxis[0], Speed / 10, Speed, Speed / 10,
                                        Acc, Acc, ArrDist[0]);
                        break;
                    case 2:
                        ret = C96F.i8196f_t_line2_move(bSlotNo, (eSINGLE_AXIS)ArrAxis[0], (eSINGLE_AXIS)ArrAxis[1],
                                            Speed / 10, Speed, Speed / 10, Acc, Acc, ArrDist[0], ArrDist[1], eInterpMode);
                        break;
                    case 3:
                        ret = C96F.i8196f_t_line3_move(bSlotNo, (eSINGLE_AXIS)ArrAxis[0], (eSINGLE_AXIS)ArrAxis[1], (eSINGLE_AXIS)ArrAxis[2],
                                            Speed / 10, Speed, Speed / 10, Acc, Acc, ArrDist[0], ArrDist[1], ArrDist[2], eInterpMode);
                        break;
                    case 4:
                    case 5:
                    case 6:
                        ret = C96F.i8196f_lines_move(bSlotNo, bitAxis, eACC_DEC_CURVE.I8196F_ACC_DEC_T_CURVE,
                                             Speed / 10, Speed, Speed / 10, Acc, Acc, FixedPulse, eInterpMode);
                        break;
                    default:
                        break;
                }

            }
            else
            {
                switch (AxisCnt)
                {
                    case 0:
                        break;
                    case 1:
                        ret = C96F.i8196f_abs_t_move(bSlotNo, (eSINGLE_AXIS)ArrAxis[0], Speed / 10, Speed, Speed / 10,
                                        Acc, Acc, ArrDist[0]);
                        break;
                    case 2:
                        ret = C96F.i8196f_abs_t_line2_move(bSlotNo, (eSINGLE_AXIS)ArrAxis[0], (eSINGLE_AXIS)ArrAxis[1],
                                            Speed / 10, Speed, Speed / 10, Acc, Acc, ArrDist[0], ArrDist[1], eInterpMode);
                        break;
                    case 3:
                        ret = C96F.i8196f_abs_t_line3_move(bSlotNo, (eSINGLE_AXIS)ArrAxis[0], (eSINGLE_AXIS)ArrAxis[1], (eSINGLE_AXIS)ArrAxis[2],
                                            Speed / 10, Speed, Speed / 10, Acc, Acc, ArrDist[0], ArrDist[1], ArrDist[2], eInterpMode);
                        break;
                    case 4:
                    case 5:
                    case 6:
                        ret = C96F.i8196f_abs_lines_move(bSlotNo, bitAxis, eACC_DEC_CURVE.I8196F_ACC_DEC_T_CURVE,
                                             Speed / 10, Speed, Speed / 10, Acc, Acc, FixedPulse, eInterpMode);
                        break;
                    default:
                        break;
                }
            }
        }

        private void btnLineStop_Click(object sender, EventArgs e)
        {
            CheckBox[] chkAxis = { chkAxis0, chkAxis1, chkAxis2, chkAxis3, chkAxis4, chkAxis5 };
            short ret = 0;
            int i = 0;
            byte bitAixs = 0;

            for (i = 0; i < 6; i++)
            {
                if (chkAxis[i].Checked)
                {
                    bitAixs = (byte)(0x0001 << i);
                    ret = C96F.i8196f_stop_move(bSlotNo, (eSINGLE_AXIS)bitAixs, eSTOP_MODE.STOP_SLOWDOWN);
                }
            }
        }

        private void btnArcMove_Click(object sender, EventArgs e)
        {
            short ret = 0;
            byte AxisX = (byte)(0x0001 << cmbARCAxisX.SelectedIndex);
            byte AxisY = (byte)(0x0001 << cmbARCAxisY.SelectedIndex);

            uint Speed = System.UInt32.Parse(txtArcSpeed.Text);
            uint Acc = Speed * 2;
            int MainAxisCenterPoint = System.Int32.Parse(txtCenterPointX.Text);
            int SlaveAxisCenterPoint = System.Int32.Parse(txtCenterPointY.Text);
            int MainAxisFinishPoint = System.Int32.Parse(txtFinishPointX.Text);
            int SlaveAxisFinishPoint = System.Int32.Parse(txtFinishPointY.Text);

            eINTERPOLATION_MODE eInterpMode = eINTERPOLATION_MODE.GENERAL_INTERP_CONFIG;
     
            eARC_DIR ArcDirection = 0;

            if (rdoArcDirN.Checked)
            { ArcDirection = eARC_DIR.ARC_DIR_CCW; }
            else
            { ArcDirection = eARC_DIR.ARC_DIR_CW; }

            if (rdoR.Checked)
            {
                ret = C96F.i8196f_t_arc2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY, Speed / 10, Speed, Speed / 10, Acc, Acc, ArcDirection,
                    MainAxisCenterPoint, SlaveAxisCenterPoint, MainAxisFinishPoint, SlaveAxisFinishPoint,
                    eInterpMode);
            }
            else
            {
                ret = C96F.i8196f_abs_t_arc2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed / 10, Speed, Speed / 10, Acc, Acc, ArcDirection, MainAxisCenterPoint, SlaveAxisCenterPoint, MainAxisFinishPoint, SlaveAxisFinishPoint,
                    eInterpMode);
            }
        }

        private void btnArcStop_Click(object sender, EventArgs e)
        {
            short ret = 0;
            byte AxisX = (byte)(0x0001 << cmbARCAxisX.SelectedIndex);
            byte AxisY = (byte)(0x0001 << cmbARCAxisY.SelectedIndex);

            ret = C96F.i8196f_stop_move(bSlotNo, (eSINGLE_AXIS)AxisX, eSTOP_MODE.STOP_SLOWDOWN);
            ret = C96F.i8196f_stop_move(bSlotNo, (eSINGLE_AXIS)AxisY, eSTOP_MODE.STOP_SLOWDOWN);
        }

        private void btnHelicalMove_Click(object sender, EventArgs e)
        {
            short ret = 0;
            byte AxisX = (byte)(0x01 << cmbHelicalAxis0.SelectedIndex);
            byte AxisY = (byte)(0x01 << cmbHelicalAxis1.SelectedIndex);
            byte AxisZ = (byte)(0x01 << cmbHelicalAxis2.SelectedIndex);

            uint Speed = System.UInt32.Parse(txtHelicalSpeed.Text);

            int CenterPointX = System.Int32.Parse(txtHelicalCP0.Text);
            int CenterPointY = System.Int32.Parse(txtHelicalCP1.Text);
            int CenterPointZ = 0;
            int lNormalDir0, lNormalDir1, lNormalDir2;
            int Angle = System.Int32.Parse(txtHelicalAngle.Text);
            int Pitch = System.Int32.Parse(txtHelicalPitch.Text);

            eINTERPOLATION_MODE eInterpMode = eINTERPOLATION_MODE.GENERAL_INTERP_CONFIG;

            if (rdoR.Checked)
            {
                CenterPointZ = 0;
                lNormalDir0 = 0;
                lNormalDir1 = 0;
                lNormalDir2 = 1;
                ret = C96F.i8196f_t_helical_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY, (eSINGLE_AXIS)AxisZ, Speed / 10, Speed, Speed / 10, Speed * 2, Speed * 2,
                    CenterPointX, CenterPointY, CenterPointZ, lNormalDir0, lNormalDir1, lNormalDir2,
                    (float)Angle, (float)Pitch, eInterpMode);
            }
            else
            {
                ret = C96F.i8196f_get_cmdcounter(bSlotNo, (eSINGLE_AXIS)AxisZ, ref CenterPointZ);

		        lNormalDir0 = 0;
		        lNormalDir1 = 0;
		        lNormalDir2 = 1;
                ret = C96F.i8196f_abs_t_helical_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY, (eSINGLE_AXIS)AxisZ, Speed / 10, Speed, Speed / 10, Speed * 2, Speed * 2,
                    CenterPointX, CenterPointY, CenterPointZ, lNormalDir0, lNormalDir1, lNormalDir2,
                    (float)Angle, (float)Pitch, eInterpMode);
            }
        }

        private void btnHelicalStop_Click(object sender, EventArgs e)
        {
            short ret = 0;
            byte AxisX = (byte)(0x01 << cmbHelicalAxis0.SelectedIndex);
            byte AxisY = (byte)(0x01 << cmbHelicalAxis1.SelectedIndex);
            byte AxisZ = (byte)(0x01 << cmbHelicalAxis2.SelectedIndex);

            ret = C96F.i8196f_stop_move(bSlotNo, (eSINGLE_AXIS)AxisX, eSTOP_MODE.STOP_SLOWDOWN);
            ret = C96F.i8196f_stop_move(bSlotNo, (eSINGLE_AXIS)AxisY, eSTOP_MODE.STOP_SLOWDOWN);
            ret = C96F.i8196f_stop_move(bSlotNo, (eSINGLE_AXIS)AxisZ, eSTOP_MODE.STOP_SLOWDOWN);
        }

        private void chkEnableConti_CheckStateChanged(object sender, EventArgs e)
        {
            short ret = 0;

            byte AxisX = 0x01;
            byte AxisY = 0x02;
            ushort GroupIndex0 = (ushort)(AxisX | AxisY);

            eINTERP_CONFIG CfgEnable;

            if (chkEnableConti.Checked)
            {
                CfgEnable = eINTERP_CONFIG.START_INTERP_CONFIG;

                btnLineMove.Enabled = false;
                btnArcMove.Enabled = false;
                btnHelicalMove.Enabled = false;
                btnResetCnt0.Enabled = false;
                btnResetCnt1.Enabled = false;
                btnResetCnt2.Enabled = false;
                btnResetCnt3.Enabled = false;
                btnResetCnt4.Enabled = false;
                btnResetCnt5.Enabled = false;
                btnResetCntAll.Enabled = false;

                btnContiStart.Enabled = true;


            }
            else
            {
                CfgEnable = eINTERP_CONFIG.CANCEL_INTERP_CONFIG;

                btnLineMove.Enabled = true;
                btnArcMove.Enabled = true;
                btnHelicalMove.Enabled = true;
                btnResetCnt0.Enabled = true;
                btnResetCnt1.Enabled = true;
                btnResetCnt2.Enabled = true;
                btnResetCnt3.Enabled = true;
                btnResetCnt4.Enabled = true;
                btnResetCnt5.Enabled = true;
                btnResetCntAll.Enabled = true;

                btnContiStart.Enabled = false;
            }

            ret = C96F.i8196f_set_conti_interp_cfg(bSlotNo, CfgEnable, GroupIndex0, 0, 0);

        }

        private void btnContiStart_Click(object sender, EventArgs e)
        {
            short ret = 0;
            int i = 0;
            int BaseDist = 10000;
            uint Speed = System.UInt32.Parse(txtContiSpeed.Text);
            int LoopTimes = System.Int32.Parse(txtContiTimes.Text);            
            eARC_DIR ArcDirection = eARC_DIR.ARC_DIR_CCW;

            byte AxisX = 0x01;
            byte AxisY = 0x02;

            eINTERPOLATION_MODE eInterpMode = eINTERPOLATION_MODE.CONTI_INTERP_CONFIG;

            for (i = 0; i < LoopTimes; i++)
            {
                ret = C96F.i8196f_t_line2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                                Speed, Speed, Speed, Speed * 2, Speed * 2, BaseDist * 2, 0, eInterpMode);

                ret = C96F.i8196f_t_arc2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed, Speed, Speed, Speed * 2, Speed * 2, ArcDirection, 0, BaseDist, BaseDist, BaseDist, eInterpMode);

                ret = C96F.i8196f_t_line2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed, Speed, Speed, Speed * 2, Speed * 2, 0, BaseDist, eInterpMode);

                ret = C96F.i8196f_t_arc2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed, Speed, Speed, Speed * 2, Speed * 2, ArcDirection, BaseDist * (-1), 0, BaseDist * (-1), BaseDist, eInterpMode);

                ret = C96F.i8196f_t_line2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed, Speed, Speed, Speed * 2, Speed * 2, BaseDist * (-2), 0, eInterpMode);

                ret = C96F.i8196f_t_arc2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed, Speed, Speed, Speed * 2, Speed * 2, ArcDirection, 0, BaseDist * (-1), BaseDist * (-1), BaseDist * (-1), eInterpMode);

                ret = C96F.i8196f_t_line2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed, Speed, Speed, Speed * 2, Speed * 2, 0, BaseDist * (-1), eInterpMode);

                ret = C96F.i8196f_t_arc2_move(bSlotNo, (eSINGLE_AXIS)AxisX, (eSINGLE_AXIS)AxisY,
                    Speed, Speed, Speed, Speed * 2, Speed * 2, ArcDirection, BaseDist, 0, BaseDist, BaseDist * (-1), eInterpMode);
           
            }            
        }

        private void btnContiStop_Click(object sender, EventArgs e)
        {
            short ret = 0;
            eSINGLE_AXIS AxisX = eSINGLE_AXIS.AXIS_0;
            eSINGLE_AXIS AxisY = eSINGLE_AXIS.AXIS_1;

            ret = C96F.i8196f_stop_move(bSlotNo, AxisX, eSTOP_MODE.STOP_SLOWDOWN);
            ret = C96F.i8196f_stop_move(bSlotNo, AxisY, eSTOP_MODE.STOP_SLOWDOWN);
        }
    }
}