using System;

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

namespace wp_CSharp02
{
    public partial class Form1 : Form
    {
        byte is_try_ok;     // try ... catch state, 1: Ok, 0: error
        float temp_single;  // temporary used 32-bit float value

        public Form1()
        {
            InitializeComponent();
        }
        
        // convert 8017H's value (-32768 ~ +32767) to float value (-10.0 ~ +10.0)
        private float convert_8017(short val)
        {
            if (val >= 0)
                return Convert.ToSingle(val) * 10.0f / 32767.0f;
            else
                return Convert.ToSingle(val) * 10.0f / 32768.0f;
        }

        // convert 87024's value (-32768 ~ +32767) to float value (-10.0 ~ +10.0)
        private float convert_87024_1(short val)
        {
            if (val >= 0)
                return Convert.ToSingle(val) * 10.0f / 32767.0f;
            else
                return Convert.ToSingle(val) * 10.0f / 32768.0f;
        }

        // convert float value (-10.0 ~ +10.0) to int16 value (-32768 ~ +32767)
        private short convert_87024(float float_val)
        {
            if (float_val == 10.0)    // upper limit
                return 32767;
            else 
                if (float_val == -10.0)  // lower limit
                    return -32768;
                else
                    if (float_val >= 0.0 && float_val < 10.0) // 0.0 ~ 10.0
                        return Convert.ToInt16(float_val * 3276.7);
                    else
                        if (float_val < 0.0 && float_val > -10.0)   // -10.0 ~ 0.0
                            return Convert.ToInt16(float_val * 3276.8);
                        else// wrong val
                        {
                            MessageBox.Show("Value should be between -10.0 to +10.0 !");
                            return 0;
                        }
        }

        private void ScanAI()
        {
            int Value = 0;
            // get AI value (short integer) at Modbus No. 9 to 12
            Quicker.UserShare.UserGetReg_Short(Convert.ToUInt16(9),out Value);
            AI_Value1.Text = float_str1(convert_8017((short)Value), 3);     // display 3 digit under "." symbol

            Quicker.UserShare.UserGetReg_Short(Convert.ToUInt16(10),out Value);
            AI_Value2.Text = float_str1(convert_8017((short)Value), 3);

            Quicker.UserShare.UserGetReg_Short(Convert.ToUInt16(11),out Value);
            AI_Value3.Text = float_str1(convert_8017((short)Value), 3);

            Quicker.UserShare.UserGetReg_Short(Convert.ToUInt16(12),out Value);
            AI_Value4.Text = float_str1(convert_8017((short)Value), 3);

            // Get short integer (16-bit signed, -32768 ~ +32767) at Modbus No.= 1 (AO 1)
            Quicker.UserShare.UserGetReg_Short(Convert.ToUInt16(1),out Value);
            AO_Value1.Text = float_str1(convert_87024_1((short)Value), 2);  // display 2 digit under "." symbol

        }

        // convert float value to string with fixed digit number under dot "." symbol'
        // float_val: a float value, for ex, 1.234567
        // dot_num: 0 ~ 6
        // for ex,  1.234567 return 1.234 if dot_num=3
        //                   return 1.23  if dot_num=2
        private string float_str1(float float_val, byte dot_num)
        {
            string str, str1;
            short jj, pos;

            // set float vale as 0 if vale is very close to 0 
            if (float_val > 0.0 && float_val < 0.000001)
                float_val = 0.0f;
        
            if (float_val < 0.0 && float_val > -0.000001)
                float_val = 0.0f;
            // dot number should be 0 to 6
            if (dot_num < 0)
                dot_num = 0;
            else
                if (dot_num > 6)
                    dot_num = 6;
        
            // search "."
            str = float_val.ToString();
            jj = (short)str.Length;
            pos = -1;
            
            for(int i = 0;i < jj;i++)
            {
                if (str.Substring(i, 1) == ".")
                    pos = (short)i;
            }

            if(pos != -1)  // "." found
                if (pos < str.Length - dot_num)
                    str1 = str.Substring(0, pos + 1 + dot_num);
                else
                {
                    jj = (short)(pos + 1 + dot_num - str.Length);
                    str1 = str;
                    for (int i = 0;i<jj;i++)
                        str1 += "0";
                }
                
            else  // "." not found
	        {
                str1 = float_val.ToString() + ".";
                for (int i = 0 ;i<dot_num;i++)
                    str1 += "0";
            }

            return str1;
        }
    
        // check if value is inside -10.0 to +10.0
        // return 1:Ok , 0:Error
        private byte check_87024(float float_val)
        {
            if (float_val > 10.0 || float_val < -10.0)
            {
                MessageBox.Show("Value should be between -10.0 to +10.0 !");
                return 0;  // error
            }
            return 1;  // ok
        }

        private void Button4_Click(object sender, EventArgs e)
        {
            int temp;
            is_try_ok = 1;  // init as Ok
            
            try
            {
                temp_single = float.Parse(AO_Value4.Text);  // for ex, if Value = 12AB.cd, error happens. However for ex.  Value = 1.15 is correct
            }
            catch
            {
                is_try_ok = 0;   // error found
                MessageBox.Show("Wrong value !");
            }

            if (is_try_ok == 0)  // error found , return 
                return;
            
            // check if value is correct
            if (check_87024(temp_single) == 0)
                return;

            temp = convert_87024(temp_single);
            // write a short integer (16-bit signed, -32768 ~ +32767) to Modbus No.=4
            Quicker.UserShare.UserSetReg_Short(Convert.ToUInt16(4),out temp);
        }

        private void Button3_Click(object sender, EventArgs e)
        {
            int temp;
            is_try_ok = 1;  // init as Ok
            try
            {
                temp_single = short.Parse(AO_Value3.Text);  // for ex, if Value = 12AB.cd, error happens. However for ex.  Value = 1.15 is correct
            }
            catch
            {
                is_try_ok = 0;   // error found
                MessageBox.Show("Wrong value !");
            }

            if (is_try_ok == 0)  // error found , return 
                return;
            // check if value is correct
            if (check_87024(temp_single) == 0)
                return;

            temp = convert_87024(temp_single);
            // write a short integer (16-bit signed, -32768 ~ +32767) to Modbus No.=3
            Quicker.UserShare.UserSetReg_Short(Convert.ToUInt16(3),out temp);
        }

        private void Button2_Click(object sender, EventArgs e)
        {
            int temp;
            is_try_ok = 1;  // init as Ok
            try
            {
                temp_single = float.Parse(AO_Value2.Text);  // for ex, if Value = 12AB.cd, error happens. However for ex.  Value = 1.15 is correct
            }
            catch
            {
                is_try_ok = 0;   // error found
                MessageBox.Show("Wrong value !");
            }
        
            if (is_try_ok == 0) // error found , return 
                return;
            // check if value is correct
            if (check_87024(temp_single) == 0)
                return;

            temp = convert_87024(temp_single);
            // write a short integer (16-bit signed, -32768 ~ +32767) to Modbus No.=2
            Quicker.UserShare.UserSetReg_Short(Convert.ToUInt16(2),out temp);

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // enable timer1
            timer1.Interval = 250;  // 250 ms
            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // scan A/I every timer1 interval
            ScanAI();
        }


    }
}