/// <summary>
 /// Method that allow access to the class
 /// </summary>
 /// <returns>Instance of the class RFIDReader</returns>
 public static RFIDReader GetInstance()
 {
     if (_instance == null)
     {
         _instance = new RFIDReader();
     }
     return(_instance);
 }
 /// <summary>
 /// This method initializes the different classes and data
 /// </summary>
 private void InitializesClassesData()
 {
     ServoMotor.GetInstance().Lock();
     RFIDReader.GetInstance();
     DisplayLoad();
     ListOfCards.GetInstance().CardsList = SDCard.GetInstance().LoadCards();
     if (ListOfCards.GetInstance().CardsList == null)
     {
         ListOfCards.GetInstance().CardsList = new ArrayList();
     }
     RestoreInitialState();
 }
        /// <summary>
        /// When the menu to add a card is selected
        /// </summary>
        private void AddCard()
        {
            switch (_addCardState)
            {
            case ADD_CARD_STATE.waitRFID:
                LCD.GetInstance().Clear();
                LCD.GetInstance().DisplayText(GT.Color.Gray, "Veuillez approcher un badge du lecteur");
                if (RFIDReader.GetInstance().IsBadgeScan)
                {
                    _addCardState = ADD_CARD_STATE.RFIDDetected;
                    LCD.GetInstance().DisplayText(GT.Color.Green, "Votre badge a ete correctement scanne", 10, LCD.GetInstance().LcdHeight / 2);
                    Thread.Sleep(2000);     // Wait 2 seconds to see the message
                }
                break;

            case ADD_CARD_STATE.RFIDDetected:
                LCD.GetInstance().Clear();
                string uid = RFIDReader.GetInstance().CurrentUid;

                if (ListOfCards.GetInstance().FindCardInlist(uid))     // If the badge scanned already exist
                {
                    _addCardState = ADD_CARD_STATE.badgeExist;
                }
                else
                {
                    _addCardState = ADD_CARD_STATE.bageDontExist;
                }
                break;

            case ADD_CARD_STATE.badgeExist:
                LCD.GetInstance().DisplayText(GT.Color.Red, "/!\\ Erreur : Ce badge est deja sauvegarde /!\\", 10, LCD.GetInstance().LcdHeight / 2);
                Thread.Sleep(2000);     // Wait 2 seconds to see the message
                RestoreInitialState();
                break;

            case ADD_CARD_STATE.bageDontExist:
                string name      = LCDTextFields.Content; // The content value of the LCD field, it's the name of the badge
                char[] charArray = name.ToCharArray();    // We split the name in a char array to make it easier to modify char by char
                int    x         = 110;                   // The position index where we're gonna write the first char

                if (LCDTextFields.ShouldBeRefresh)        // If we need to refresh because we have modify a char or the position of the cursor
                {
                    LCD.GetInstance().Clear();
                    LCD.GetInstance().DisplayText(GT.Color.Gray, "Votre badge :", 10, LCD.GetInstance().LcdHeight / 2);
                    LCD.GetInstance().DisplayText(GT.Color.Gray, "Pour valider le nom, appuyer sur le joystick", 10, LCD.GetInstance().LcdHeight - 20);
                    for (int i = 0; i < charArray.Length; i++)
                    {
                        if (i == LCDTextFields.CursorPosition)     // If the cursorposition is at this char
                        {
                            LCD.GetInstance().DisplayText(GT.Color.Blue, charArray[i].ToString(), x, LCD.GetInstance().LcdHeight / 2);
                        }
                        else
                        {
                            LCD.GetInstance().DisplayText(GT.Color.Black, charArray[i].ToString(), x, LCD.GetInstance().LcdHeight / 2);
                        }
                        x += 10;     // Increment the X position on the LCD
                    }
                    LCDTextFields.ShouldBeRefresh = false;
                }

                if (_joystickX.Read() < JOYSTICK_UP_RIGHT)       // If the joystick is up
                {
                    charArray[LCDTextFields.CursorPosition]++;   // Increment the char ex : A -> B
                    LCDTextFields.ShouldBeRefresh = true;
                    Thread.Sleep(100);                           // Wait 0.1 second to prevent the letter from scrolling too fast
                }
                else if (_joystickX.Read() > JOYSTICK_DOWN_LEFT) // If the joystick is down
                {
                    charArray[LCDTextFields.CursorPosition]--;   // ecrement the char ex : B -> A
                    LCDTextFields.ShouldBeRefresh = true;
                    Thread.Sleep(100);                           // Wait 0.1 second to prevent the letter from scrolling too fast
                }


                if (_joystickY.Read() < JOYSTICK_UP_RIGHT)                   // If the joystick is right
                {
                    LCDTextFields.CursorPosition++;                          // Move the cursor to the next char
                    if (LCDTextFields.CursorPosition > charArray.Length - 1) // If the cursor get out of the range of the char array
                    {
                        LCDTextFields.CursorPosition = 0;                    // Move to the first position of the char array
                    }
                    LCDTextFields.ShouldBeRefresh = true;
                    Thread.Sleep(200);                                       // Wait 0.2 seconds to prevent the cursor from moving too fast
                }
                else if (_joystickY.Read() > JOYSTICK_DOWN_LEFT)             // If the joystick is left
                {
                    LCDTextFields.CursorPosition--;                          // Move the cursor to the previous char
                    if (LCDTextFields.CursorPosition < 0)                    // If the cursor get out of the range of the char array
                    {
                        LCDTextFields.CursorPosition = charArray.Length - 1; // Move to the last position of the char array
                    }
                    LCDTextFields.ShouldBeRefresh = true;
                    Thread.Sleep(200);     // Wait 0.2 seconds to prevent the cursor from moving too fast
                }

                LCDTextFields.Content = new string(charArray); // Set the LCD text field with the value of the modify char array

                if (!_joystickButton.Read())                   // If joystick button is press
                {
                    _addCardState = ADD_CARD_STATE.save;
                }
                break;

            case ADD_CARD_STATE.save:
                try
                {
                    uid  = RFIDReader.GetInstance().CurrentUid;    // Get the uid of the badge that was scanned
                    name = LCDTextFields.Content;
                    ListOfCards.GetInstance().AddCardToList(name, uid);
                    SDCard.GetInstance().SaveCards(ListOfCards.GetInstance().CardsList);
                    _addCardState = ADD_CARD_STATE.successMSG;
                }
                catch (Exception e)
                {
                    _addCardState = ADD_CARD_STATE.errorMSG;
                }
                break;

            case ADD_CARD_STATE.errorMSG:
                DisplayError();
                Thread.Sleep(2000);
                RestoreInitialState();
                break;

            case ADD_CARD_STATE.successMSG:
                DisplaySave();
                LCD.GetInstance().DisplayText(GT.Color.Green, "Le badge a bien ete ajoute", 10, LCD.GetInstance().LcdHeight / 2);
                Thread.Sleep(2000);
                RestoreInitialState();
                break;

            default:
                _addCardState = ADD_CARD_STATE.waitRFID;
                break;
            }
        }
        /// <summary>
        /// When no menu is selected
        /// </summary>
        private void InitialState()
        {
            switch (_scanCardState)
            {
            case SCAN_CARD_STATE.waitRFID:
                if (RFIDReader.GetInstance().IsBadgeScan)
                {
                    _scanCardState = SCAN_CARD_STATE.RFIDDetected;
                }
                break;

            case SCAN_CARD_STATE.RFIDDetected:
                if (_servoState == SERVO_STATE.close)     // If the servo is lock
                {
                    bool isValid = ListOfCards.GetInstance().FindCardInlist(RFIDReader.GetInstance().CurrentUid);
                    if (isValid)
                    {
                        _scanCardState = SCAN_CARD_STATE.RFIDValid;
                    }
                    else
                    {
                        _scanCardState = SCAN_CARD_STATE.RFIDInvalid;
                    }
                }
                else
                {
                    _scanCardState = SCAN_CARD_STATE.RFIDInvalid;
                }
                break;

            case SCAN_CARD_STATE.RFIDValid:
                _servoState    = SERVO_STATE.open;
                _scanCardState = SCAN_CARD_STATE.waitRFID;
                DeleteCurrentBadgescan();
                break;

            case SCAN_CARD_STATE.RFIDInvalid:
                _servoState    = SERVO_STATE.close;
                _scanCardState = SCAN_CARD_STATE.waitRFID;
                DeleteCurrentBadgescan();
                break;

            default:
                _scanCardState = SCAN_CARD_STATE.waitRFID;
                break;
            }

            switch (_servoState)
            {
            case SERVO_STATE.open:
                ServoMotor.GetInstance().Unlock();
                _secuTimer.Start();
                break;

            case SERVO_STATE.close:
                ServoMotor.GetInstance().Lock();
                _secuTimer.Stop();
                break;

            default:
                _servoState = SERVO_STATE.close;
                break;
            }

            if (_joystickX.Read() > JOYSTICK_DOWN_LEFT) // If the joystick is down
            {
                _menu++;
                if (_menu > 4)
                {
                    _menu = 0;
                }
                DisplayMainMenu(_menu);                     // It is not removed from the test to prevent the lcd flashing
                Thread.Sleep(100);                          // Wait 0.1 second to prevent the menu from scrolling too fast
            }
            else if (_joystickX.Read() < JOYSTICK_UP_RIGHT) // The joystick is up
            {
                _menu--;
                if (_menu < 0)
                {
                    _menu = 4;
                }
                DisplayMainMenu(_menu); // It is not removed from the test to prevent the lcd flashing
                Thread.Sleep(100);      // Wait 0.1 second to prevent the menu from scrolling too fast
            }
        }
 /// <summary>
 /// This method clear the current badge that is scan by the RFIDReader
 /// </summary>
 private void DeleteCurrentBadgescan()
 {
     RFIDReader.GetInstance().CurrentUid  = "";
     RFIDReader.GetInstance().IsBadgeScan = false;
 }