def ProcessDigitKey(key):

    # Only process key if we are in a time on or off edit mode.
    if GD.currentMode in (GD.MODE_PROG_ON_AT, GD.MODE_PROG_OFF_AT):

        # Convert keycode to character '0' to '9'
        key = chr(key - 2)

        if GD.currentMode == GD.MODE_PROG_ON_AT:
            # Update and display the on time. Call to modify will return -ve when all digits done and +ve if OK.
            status = zones.zoneTimes.ModifyTime(GD.ON_TIME_INDEX, key)
            display.DisplayProgOnTime()

        else:
            # Update and display the off time. Call to modify will return -ve when all digits done and +ve if OK.
            status = zones.zoneTimes.ModifyTime(GD.OFF_TIME_INDEX, key)
            display.DisplayProgOffTimeAndDays()

        # Update save and valid prompts now we have changed the data
        display.DisplayBottomLeftInfoPrompt()
        display.DisplayBottomRightInfoPrompt()

        # Check to see if we have edited all the digits.
        if status < 0:
            # Return to time programming mode.
            GD.currentMode = GD.MODE_PROG_TIME
            display.DisplayKeyboardImage(useMode=GD.currentMode)

    return 1
def ProcessExitKey(zone):

    #  global GD.exitPending

    # Keep the current mode so we can check if it changes and we need to re-display the keyboard.
    lastCurrentMode = GD.currentMode

    # If the data has not changed or the user has pressed EXIT at the 'Save or Exit?' prompt we will exit back to a select mode.
    if zones.zoneTimes.CheckIfDataChanged() == False or GD.exitPending == True:

        # Clear info messages.
        display.DisplayBottomRightInfoPrompt()
        display.DisplayBottomLeftInfoPrompt(GD.BLANK_PROMPT)
        display.DisplayZoneMode()

        # No exit pending now.
        GD.exitPending = False

        # Move back to a select mode. Use correct select for rad, ufh or sys.
        if zone < 14:
            ProcessRadKey(zone)
        elif zone < 30:
            ProcessUfhKey(zone)
        else:
            keysSystem.ProcessImmersionTimesKey(zone)

    # We have changed the data so we will set exit pending flag and prompt for save or exit.
    else:
        GD.exitPending = True
        display.DisplayBottomLeftInfoPrompt()

    return 1
def SwitchToRunMode():

    # Clear all the prompts.
    display.DisplayZoneMode()
    display.TopRightInfoPrompt(GD.BLANK_PROMPT)
    display.DisplayProgOnTime(GD.BLANK_PROMPT)
    display.DisplayProgOffTimeAndDays(GD.BLANK_PROMPT)
    display.DisplayEntries(GD.BLANK_PROMPT)
    display.DisplayBottomLeftInfoPrompt(GD.BLANK_PROMPT)
    display.DisplayBottomRightInfoPrompt(GD.BLANK_PROMPT)

    # Set system bits as required.
    system.SetModeOutputControlBitsFromConfigBits()

    # Switch to run mode.
    GD.currentMode = GD.MODE_RUN

    # Put display into waiting for a press mode.
    display.WriteToDisplay(GD.BACKLIGHT_OFF)
    display.DisplayForm(GD.BLANK_SCREEN_FORM)
    display.DisplayPressToStart()
    display.WriteToDisplay(GD.BACKLIGHT_LOW)

    # For android screen
    display.DisplayMiddleLeftInfoPrompt(GD.PRESS_ANY_KEY_PROMPT)

    # Clear any boost presses so they are not there when we restart later.
    GD.boostPresses = 0

    # Start a zones check to update any changes to zones.
    GD.checkZone = 0
def ProcessPreviousProgramEntrytKey(zone):

    # Return to initial state if we are in ON AT, OFF AT or day select mode and turn all pointers on.
    if GD.currentMode in (GD.MODE_PROG_ON_AT, GD.MODE_PROG_OFF_AT,
                          GD.MODE_PROG_DAYS_ON):
        GD.currentMode = GD.MODE_PROG_DAY if GD.currentMode == GD.MODE_PROG_DAYS_ON else GD.MODE_PROG_TIME

    # Display the previous programming data entry.
    display.DisplayProgEntry(-1)
    display.DisplayBottomRightInfoPrompt()

    return 1
def ProcessEnableDisableKey(zone):

    # Only allow disable if we are in days entry mode.
    if GD.currentMode == GD.MODE_PROG_DAYS_ON:
        # Do disable/enable (toggle action).
        zones.zoneTimes.ModifyDay(GD.DAYS_INDEX, GD.DAYS_DISABLED)
        # Update save prompt as we have changed the data.
        display.DisplayBottomLeftInfoPrompt()
        display.DisplayBottomRightInfoPrompt()
        # Display the Current programming data entry. Force a display update.
        display.DisplayProgEntry(0, forceUpdate=True)

    return 1
def ProcessClearKey(zone):

    #  global GD.clearPending

    if GD.currentMode == GD.MODE_PROG_ON_AT:

        # Clear the on time.
        zones.zoneTimes.ClearTime(GD.ON_TIME_INDEX)
        # Display the new time.
        display.DisplayProgOnTime()

    elif GD.currentMode == GD.MODE_PROG_OFF_AT:

        # Clear the off time.
        zones.zoneTimes.ClearTime(GD.OFF_TIME_INDEX)
        # Display the new time.
        display.DisplayProgOffTimeAndDays()

    elif GD.currentMode == GD.MODE_PROG_DAYS_ON and zones.zoneTimes.CheckIfDisabled(
            GD.DAYS_INDEX) == False:

        # Clear the days if we are not disabled.
        zones.zoneTimes.ClearDays(GD.DAYS_INDEX)
        # Display the new day info. Days info is displayed with the off time.
        display.DisplayProgOffTimeAndDays()

    elif GD.currentMode in (GD.MODE_PROG_TIME, GD.MODE_PROG_DAY):

        if GD.clearPending == True:
            GD.clearPending = False
            # Clear the on time
            zones.zoneTimes.ClearTime(GD.ON_TIME_INDEX)
            # Clear the off time
            zones.zoneTimes.ClearTime(GD.OFF_TIME_INDEX)
            # Clear the days
            zones.zoneTimes.ClearDays(GD.DAYS_INDEX)

            # Display the on time, off time and days.
            display.DisplayProgOnTime()
            display.DisplayProgOffTimeAndDays()

        else:
            GD.clearPending = True

    # Update info prompts now we have chaged the data
    display.DisplayBottomLeftInfoPrompt()
    display.DisplayBottomRightInfoPrompt()

    return 1
def ProcessWakeupKey(zone):

    # Start up the display by setting the correct form. Clear any info messages.
    display.DisplayForm(GD.MAIN_SCREEN_FORM)
    display.DisplayBottomLeftInfoPrompt(GD.BLANK_PROMPT)
    display.DisplayBottomRightInfoPrompt()

    # Check if the system is on or off. If we are on we display the rad select screen. If we are off we display the system screen.
    if system.systemControl[GD.SYSTEM_OFF_MODE].CheckIfBitHigh() == True:
        ProcessSystemKey(-1)
    else:
        ProcessRadKey(-1)

    display.WriteToDisplay(GD.BACKLIGHT_HALF)

    return 1
def ProcessDayOfWeekKey(key):

    # Only process key if we are in correct mode and not disabled.
    if GD.currentMode == GD.MODE_PROG_DAYS_ON and zones.zoneTimes.CheckIfDisabled(
            GD.DAYS_INDEX) == False:
        # Convert keycode to values 0 to 9 so we can use as index to string of days.
        key = key - 60

        # Update the day.
        zones.zoneTimes.ModifyDay(GD.DAYS_INDEX, key)
        # Display the new day info.
        display.DisplayProgOffTimeAndDays()

        # Update the save and valid prompts now we have changed the data.
        display.DisplayBottomLeftInfoPrompt()
        display.DisplayBottomRightInfoPrompt()

    return 1
def ProcessProgramKey(zone):

    # Switch to the program keyboard (time entry).
    display.DisplayKeyboardImage(GD.TIME_SELECT_KEYBOARD_IMAGE)

    # Say we are in programming mode. We start in time entry mode.
    GD.currentMode = GD.MODE_PROG_TIME

    # Clear the zone select data ready for displaying programming data fields.
    display.DisplayMiddleLeftInfoPrompt(GD.BLANK_PROMPT)

    # Read the programmed times and display the 1st programming data entry. Force a display update.
    zones.ReadZoneTimes(zone)
    display.DisplayProgEntry(1, forceUpdate=True)
    display.DisplayBottomLeftInfoPrompt()
    display.DisplayBottomRightInfoPrompt()

    return 1
def ProcessNewKey(zone):

    #Limit number of entries to a reasonable number.
    if zones.zoneTimes.GetNumberOfProgramEntries() < 8:
        # Create new entry and get the number.
        newEntryNumber = zones.zoneTimes.AddNewEntry()

        # Return to initial state if we are in ON AT, OFF AT or day select mode.
        if GD.currentMode in (GD.MODE_PROG_ON_AT, GD.MODE_PROG_OFF_AT,
                              GD.MODE_PROG_DAYS_ON):
            GD.currentMode = GD.MODE_PROG_DAY if GD.currentMode == GD.MODE_PROG_DAYS_ON else GD.MODE_PROG_TIME

        # Update info prompts now we have changed the data.
        display.DisplayBottomLeftInfoPrompt()
        display.DisplayBottomRightInfoPrompt()

        # Display the new programming data entry.
        display.DisplayProgEntry(newEntryNumber, forceUpdate=True)

    return 1
def ProcessSaveKey(zone):

    # Only save if a change has been made.
    if zones.zoneTimes.CheckIfDataChanged() == True:
        zones.zoneTimes.UpdateProgramEntries()

    # Return to initial state if we are in ON AT, OFF AT or day select mode.
    if GD.currentMode in (GD.MODE_PROG_ON_AT, GD.MODE_PROG_OFF_AT,
                          GD.MODE_PROG_DAYS_ON):
        GD.currentMode = GD.MODE_PROG_DAY if GD.currentMode == GD.MODE_PROG_DAYS_ON else GD.MODE_PROG_TIME

    # Clear the flag now we have saved data and update prompts.
    GD.exitPending = False
    display.DisplayBottomLeftInfoPrompt()
    display.DisplayBottomRightInfoPrompt()

    # We need to re-display as the current entry may be blank and will be removed on save. Go back to 1st entry.
    display.DisplayProgEntry(1, forceUpdate=True)

    return 1
def ProcessDaysKey(zone):

    #We only process key if we are NOT already in day edit mode
    if GD.currentMode != GD.MODE_PROG_DAYS_ON:

        # Say we are now in day edit mode.
        GD.currentMode = GD.MODE_PROG_DAYS_ON

        # Switch to the day entry program keyboard.
        display.DisplayKeyboardImage(GD.DAY_SELECT_KEYBOARD_IMAGE)

        # Check if any edit has been aborted and if it has restore the original data. No need to update
        # display as we do this below.
        CheckForEditAbort(updateDisplay=False)

        # Update info prompts.
        display.DisplayBottomLeftInfoPrompt()
        display.DisplayBottomRightInfoPrompt()

        # Display the Current programming data entry. Force a display update.
        display.DisplayProgEntry(0, forceUpdate=True)

    return 1