/***************************************************************************
                   ###### #######   ##   ###### #######
                   ##        #     # ##     #   ##
                     ####    #    ##  #    ##   ## ###
                   #    #    #   #######   ##   ##
                    #####    #   #     #    #   #######

            #     #    ##     ####   #    #  #  #    ## ######
            ##   ##   ####   ##   ## #    #  #  ###  ## #
            # #  ##   #  #  ##       ######  #  # ## ## ######
            # # # #  ###### ##     # #    #  #  #  #### #
            # ### #  #    ## ######  #    #  #  #   ### ######  *
        /***************************************************************************/
        /// <summary>
        /// 
        /// </summary>
        /// <param name="eevent"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private Tab3_state Magellan_FSM(Tab3_event eevent)
        {
            Tab3_state next_state;
            string request;
            string keyData;

            next_state = state;

            if (t3_protocol == Tab3_protocol.NoneCTS)
            {
                switch (state)
                {
                    case Tab3_state.Idle:
                        // Write code
                        if (eevent == Tab3_event.Run_click)
                        {
                            if (Tab3_open_port() == true) next_state = Tab3_state.Start;
                            else
                            {
                                // @Todo
                                MessageBox.Show("ComPort Can not Open", "Error",
                                MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                            }
                        }
                        break;

                    case Tab3_state.Start:
                        // Write code
                        if (eevent == Tab3_event.Send_click)
                        {
                            if (t3_mode == Tab3_mode.OneTime)
                            {
                                request = Tab3_Data_text.Text;
                                request = request.Replace('\n', '\r');
                                Add_tab3_log("\nStart Transaction \n", LogMsgType.Normal, DateTime.Now);
                                if (Tab3_SendData(request) == true)
                                {
                                    start_tab3_timer(Pack_Timer);
                                    next_state = Tab3_state.Wait_Trans;
                                }
                            }
                            else
                            {
                                // @Todo: Implement Multiple time state
                            }
                        }
                        else if (eevent == Tab3_event.Receive)
                        {
                            Add_tab3_log(Tab3_serial_buf.Text, LogMsgType.Incoming, DateTime.Now);
                            Tab3_serial_buf.Clear();
                        }
                        break;

                    case Tab3_state.Wait_Trans:
                        // Write code
                        if (eevent == Tab3_event.Receive)
                        {
                            if (Tab3_serial_buf.Text == null) break;
                            else if (Tab3_serial_buf.Text.Length >= 4) keyData = Tab3_serial_buf.Text.Substring(0, 4);
                            else break;

                            if (keyData == "#+BS")
                            {
                                // get total_item & item_count
                                Add_tab3_log(Tab3_serial_buf.Text, LogMsgType.Incoming, DateTime.Now);
                                Tab3_SendData("#+NL001\r");
                                total_item = Convert.ToInt16(Tab3_serial_buf.Text.Substring(4, 3));
                                item_count = 0;

                                // Start timer
                                start_tab3_timer(Trans_Timer);
                                start_tab3_timer(Pack_Timer);

                                // Next state
                                next_state = Tab3_state.In_Trans;
                            }
                            else
                            {
                                Add_tab3_log(Tab3_serial_buf.Text, LogMsgType.Incoming, DateTime.Now);
                                reset_trans();
                                state = Tab3_state.Start;
                                MessageBox.Show("Transaction Error", "Error");
                            }
                            Tab3_serial_buf.Clear();
                        }
                        break;

                    case Tab3_state.In_Trans:
                        // Write code
                        if (eevent == Tab3_event.Receive)
                        {
                            if (Tab3_serial_buf.Text != null)
                            {
                                item_data = Tab3_Parser();
                                if (item_data != "")
                                {
                                    stop_tab3_timer(Pack_Timer, false);
                                    item_count++;
                                    start_tab3_timer(Pack_Timer);
                                    start_tab3_timer(InterChar_Timer);
                                    next_state = Tab3_state.Send_PC;
                                }
                            }
                        }
                        break;

                    case Tab3_state.Send_PC:
                        // Write code
                        if (eevent == Tab3_event.Inter_char_Timeout)
                        {
                            Send_data2PC(item_data);
                            if (item_count < total_item)
                            {
                                next_state = Tab3_state.In_Trans;
                            }
                            else
                            {
                                // Add Log
                                Add_tab3_log("Item Received = " + item_count + "\n", LogMsgType.Warning, DateTime.Now);
                                Add_tab3_log("Total items = " + total_item + "\n", LogMsgType.Warning, DateTime.Now);
                                Add_tab3_log("Stop Transaction \n", LogMsgType.Normal, DateTime.Now);

                                // Reset transaction
                                reset_trans();
                                next_state = Tab3_state.Start;
                            }
                        }
                        break;
                    default:
                        reset_trans();
                        break;
                }
            }
            else if (t3_protocol == Tab3_protocol.CTS)
            {
                switch (state)
                {
                    case Tab3_state.Idle:
                        // Write code
                        if (eevent == Tab3_event.Run_click)
                        {
                            if (Tab3_open_port() == true)
                            {
                                next_state = Tab3_state.Start;
                                Tab3_serialPort.RtsEnable = true;
                            }
                            else
                            {
                                // @Todo
                                MessageBox.Show("ComPort Can not Open", "Error",
                                MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                            }
                        }
                        break;

                    case Tab3_state.Start:
                        // Write code
                        if (eevent == Tab3_event.Send_click)
                        {
                            if (t3_mode == Tab3_mode.OneTime)
                            {
                                request = Tab3_Data_text.Text;
                                request = request.Replace('\n', '\r');
                                Add_tab3_log("\n Start Transaction \n", LogMsgType.Normal, DateTime.Now);
                                if (Tab3_SendData(request) == true)
                                {
                                    start_tab3_timer(Pack_Timer);
                                    next_state = Tab3_state.Wait_Trans;
                                }
                            }
                            else
                            {
                                // @Todo: Implement Multiple time state
                            }
                        }
                        else if (eevent == Tab3_event.Receive)
                        {
                            Add_tab3_log(Tab3_serial_buf.Text, LogMsgType.Incoming, DateTime.Now);
                            if (t3_protocol == Tab3_protocol.CTS)
                            {
                                Tab3_serialPort.RtsEnable = false;
                                Tab3_serialPort.RtsEnable = true;
                            }
                            Tab3_serial_buf.Clear();
                        }
                        break;

                    case Tab3_state.Wait_Trans:
                    case Tab3_state.In_Trans:
                        // Write code
                        if (eevent == Tab3_event.Receive)
                        {
                            if (Tab3_serial_buf.Text != null)
                            {
                                item_data = Tab3_Parser();
                                if (item_data != "")
                                {
                                    stop_tab3_timer(Pack_Timer, false);
                                    item_count++;
                                    start_tab3_timer(Pack_Timer);
                                    start_tab3_timer(InterChar_Timer);
                                    next_state = Tab3_state.Send_PC;
                                }
                            }
                        }
                        break;

                    case Tab3_state.Send_PC:
                        // Write code
                        if (eevent == Tab3_event.Inter_char_Timeout)
                        {
                            Send_data2PC(item_data);
                            next_state = Tab3_state.In_Trans;
                        }
                        break;
                    default:
                        reset_trans();
                        break;
                }
            }
            else {
                MessageBox.Show("Can not define protocol is: Bmode or New Protocol", "Error");
            }

            return next_state;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private Tab3_state Cradle_FSM(Tab3_event e, string data)
        {
            Tab3_state next_state;

            next_state = state;
            switch (state)
            {
                case Tab3_state.Idle:
                    // Write code

                    break;
                case Tab3_state.Start:
                    // Write code

                    break;
                case Tab3_state.Wait_Trans:
                    // Write code

                    break;
                case Tab3_state.In_Trans:
                case Tab3_state.Send_PC:
                default:
                    next_state = Tab3_state.Idle;
                    break;
            }
            return Tab3_state.Idle;
        }