/* Copyright 2023 Dual Tachyon
 * https://github.com/DualTachyon
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 */

#include <string.h>
#include <stdlib.h>  // abs()
#include "bitmaps.h"
#include "driver/uart.h"
#include "app/dtmf.h"
#include "app/menu.h"
#include "board.h"
#include "dcs.h"
#include "driver/backlight.h"
#include "driver/bk4819.h"
#include "driver/st7565.h"
#include "external/printf/printf.h"
#include "frequencies.h"
#include "helper/battery.h"
#include "misc.h"
#include "settings.h"
#include "ui/helper.h"
#include "ui/inputbox.h"
#include "ui/menu.h"
#include "ui/ui.h"
#include "chinese.h"

void insertNewline(char a[], int index,int len) {

    if(index < 0 || index >= len || len >= 63) {
        return;
    }
    for (int i = len; i >= index; i--) {
        a[i + 1] = a[i];
    }
    a[index] = '\n';
    a[len + 1] = '\0'; // Null-terminate the string
}

const t_menu_item MenuList[] =
        {
//   text,     voice ID,                               menu ID
                {/*"Step",*/   VOICE_ID_FREQUENCY_STEP,                MENU_STEP          ,步进频率},
                {/*"RxDCS",*/  VOICE_ID_DCS,                           MENU_R_DCS         ,接收数字亚音}, // was "R_DCS"
                {/*"RxCTCS",*/ VOICE_ID_CTCSS,                         MENU_R_CTCS        ,接收模拟亚音}, // was "R_CTCS"
                {/*"TxDCS",*/  VOICE_ID_DCS,                           MENU_T_DCS         ,发送数字亚音}, // was "T_DCS"
                {/*"TxCTCS",*/ VOICE_ID_CTCSS,                         MENU_T_CTCS        ,发送模拟亚音}, // was "T_CTCS"
                {/*"TxODir",*/ VOICE_ID_TX_OFFSET_FREQUENCY_DIRECTION, MENU_SFT_D         ,频差方向}, // was "SFT_D"
                {/*"TxOffs",*/ VOICE_ID_TX_OFFSET_FREQUENCY,           MENU_OFFSET        ,频差频率}, // was "OFFSET"
                {/*"Scramb",*/ VOICE_ID_SCRAMBLER_ON,                  MENU_SCR           ,加密}, // was "SCR"
                {/*"BusyCL",*/ VOICE_ID_BUSY_LOCKOUT,                  MENU_BCL           ,遇忙禁发}, // was "BCL"
                {/*"Compnd",*/ VOICE_ID_INVALID,                       MENU_COMPAND       ,压扩},
                {/*"ChSave",*/ VOICE_ID_MEMORY_CHANNEL,                MENU_MEM_CH        ,存置信道}, // was "MEM-CH"
                {/*"ChDele",*/ VOICE_ID_DELETE_CHANNEL,                MENU_DEL_CH        ,删除信道}, // was "DEL-CH"
                {/*"ChName",*/ VOICE_ID_INVALID,                       MENU_MEM_NAME      ,命名信道},
                {/*"SList",*/  VOICE_ID_INVALID,                       MENU_S_LIST        ,信道扫描列表},
                {/*"SList1",*/ VOICE_ID_INVALID,                       MENU_SLIST1        ,扫描列表1},
                {/*"SList2",*/ VOICE_ID_INVALID,                       MENU_SLIST2        ,扫描列表2},
                {/*"ScnRev",*/ VOICE_ID_INVALID,                       MENU_SC_REV        ,搜索恢复模式},
                {/*"TxTOut",*/ VOICE_ID_TRANSMIT_OVER_TIME,            MENU_TOT           ,发送超时}, // was "TOT"
                {/*"BatSav",*/ VOICE_ID_SAVE_MODE,                     MENU_SAVE          ,省电模式}, // was "SAVE"
                {/*"Mic",*/    VOICE_ID_INVALID,                       MENU_MIC           ,麦克风增益},
                {/*"ChDisp",*/ VOICE_ID_INVALID,                       MENU_MDF           ,信道显示模式}, // was "MDF"
             //   {/*"POnMsg",*/ VOICE_ID_INVALID,                       MENU_PONMSG        ,开机显示},
                {/*"BackLt",*/ VOICE_ID_INVALID,                       MENU_ABR           ,自动背光}, // was "ABR"
                {/*"BLMax",*/  VOICE_ID_INVALID,                       MENU_ABR_MAX       ,背光亮度},
                {/*"MDCID",*/  VOICE_ID_INVALID,                       MENU_MDC_ID         ,MDC_ID},

                {/*"Roger",*/  VOICE_ID_INVALID,                       MENU_ROGER         ,首尾音},

                {/*"STE",*/    VOICE_ID_INVALID,                       MENU_STE           ,尾音消除},
                {/*"RP STE",*/ VOICE_ID_INVALID,                       MENU_RP_STE        ,过中继尾音消除},
                {/*"1 Call",*/ VOICE_ID_INVALID,                       MENU_1_CALL        ,按键即呼},

#ifdef ENABLE_DTMF_CALLING
                {/*"ANI ID",*/ VOICE_ID_ANI_CODE,                      MENU_ANI_ID        ,DTMF_ID},
#endif
                {/*"UPCode",*/ VOICE_ID_INVALID,                       MENU_UPCODE        ,DTMF上线码},
                {/*"DWCode",*/ VOICE_ID_INVALID,                       MENU_DWCODE        ,DTMF下线码},
                {/*"PTT ID",*/ VOICE_ID_INVALID,                       MENU_PTT_ID        ,DTMF发送},
                {/*"D ST",*/   VOICE_ID_INVALID,                       MENU_D_ST          ,DTMF侧音},
#ifdef ENABLE_DTMF_CALLING
                {/*"D Resp",*/ VOICE_ID_INVALID,                       MENU_D_RSP         ,DTMF响应},
                {/*"D Hold",*/ VOICE_ID_INVALID,                       MENU_D_HOLD        ,DTMF复位},
#endif
                {/*"D Prel",*/ VOICE_ID_INVALID,                       MENU_D_PRE         ,DTMF预载波},
#ifdef ENABLE_DTMF_CALLING
                {/*"D List",*/ VOICE_ID_INVALID,                       MENU_D_LIST        ,DTMF联系人},
#endif
                {/*"D Live",*/ VOICE_ID_INVALID,                       MENU_D_LIVE_DEC    ,DTMF显示}, // live DTMF decoder
#ifdef ENABLE_AM_FIX//1
                {/*"AM Fix",*/ VOICE_ID_INVALID,                       MENU_AM_FIX        ,AM自动增益},
#endif
#ifdef ENABLE_AM_FIX_TEST1//0
                {/*"AM FT1",*/ VOICE_ID_INVALID,                       MENU_AM_FIX_TEST1  ,""},
#endif

                {/*"RxMode",*/ VOICE_ID_DUAL_STANDBY,                  MENU_TDR           ,收发模式},
                {/*"Sql",*/    VOICE_ID_SQUELCH,                       MENU_SQL           ,静噪等级},

                // hidden menu items from here on
                // enabled if pressing both the PTT and upper side button at power-on
                {/*"F Lock",*/ VOICE_ID_INVALID,                       MENU_F_LOCK        ,频段解锁},
//                {/*"Tx 200",*/ VOICE_ID_INVALID,                       MENU_200TX         ,两百M发射}, // was "200TX"
//                {/*"Tx 350",*/ VOICE_ID_INVALID,                       MENU_350TX         ,三百五十M发射}, // was "350TX"
//                {/*"Tx 500",*/ VOICE_ID_INVALID,                       MENU_500TX         ,五百M发射}, // was "500TX"
//                {/*"350 En",*/ VOICE_ID_INVALID,                       MENU_350EN         ,三百五十M接收}, // was "350EN"
#ifdef ENABLE_F_CAL_MENU//0
                {/*"FrCali",*/ VOICE_ID_INVALID,                       MENU_F_CALI        ,""}, // reference xtal calibration
#endif
                {/*"BatCal",*/ VOICE_ID_INVALID,                       MENU_BATCAL        ,电池调压}, // battery voltage calibration
               {/*"BatTyp",*/ VOICE_ID_INVALID,                       MENU_BATTYP        ,电池大小}, // battery type 1600/2200mAh
                {/*"Reset",*/  VOICE_ID_INITIALISATION,                MENU_RESET         ,参数复位}, // might be better to move this to the hidden menu items ?

            //   {/*"",*/       VOICE_ID_INVALID,                       0xff               ,"\x00"}  // end of list - DO NOT delete or move this this
        };


const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK;
const char gSubMenu_SFT_D[][10] =//4
        {
//                "OFF",
//                "+",
//                "-"
                发送等于接收,
                发送等于接收加偏移,
                发送等于接收减偏移

        };



const char gSubMenu_OFF_ON[][3] =//4
        {
//                "OFF",
//                "ON"
                关闭,
                开启
        };

const char gSubMenu_SAVE[][4] =//4
        {
//                "OFF",
//                "1:1",
//                "1:2",
//                "1:3",
//                "1:4"

                关闭,
                一级,
                二级,
                三级,
                四级

        };

const char gSubMenu_TOT[][5] = //7
        {
//                "30 sec",
//                "1 min",
//                "2 min",
//                "3 min",
//                "4 min",
//                "5 min",
//                "6 min",
//                "7 min",
//                "8 min",
//                "9 min",
//                "15 min"

 三十秒 ,
 一分 ,
 两分,
 三分 ,
 四分 ,
 五分 ,
 六分 ,
 七分 ,
 八分 ,
 九分 ,
 十五分

        };

const char *gSubMenu_RXMode[] =
        {

//                "MAIN\nONLY",        // TX and RX on main only
//                "DUAL RX\nRESPOND", // Watch both and respond
//                "CROSS\nBAND",        // TX on main, RX on secondary
//                "MAIN TX\nDUAL RX"    // always TX on main, but RX on both
                主信道接收发射,        // TX and RX on main only
                双信道接收, // Watch both and respond
                主信道发射副信道接收,        // TX on main, RX on secondary
                主信道发射双信道接收    // always TX on main, but RX on both

        };

#ifdef ENABLE_VOICE
const char gSubMenu_VOICE[][4] =
{
    "OFF",
    "CHI",
    "ENG"
};
#endif

const char gSubMenu_SC_REV[][10] =//8
        {
//                "TIMEOUT",
//                "CARRIER",
//                "STOP"
                遇信号5秒后搜索  ,
                信号停止后搜索  ,
                遇信号后停止搜索

        };

const char *gSubMenu_MDF[] =
        {
//                "FREQ",
//                "CHANNEL\nNUMBER",
//                "NAME",
//                "NAME\n+\nFREQ"
                频率,
                信道号,
                名称,
                名称加频率
        };

#ifdef ENABLE_ALARM
const char gSubMenu_AL_MOD[][5] =
{
    "SITE",
    "TONE"
};
#endif
#ifdef ENABLE_DTMF_CALLING
const char gSubMenu_D_RSP[][10] =//11
        {
//                "DO\nNOTHING",
//                "RING",
//                "REPLY",
//                "BOTH"
                不响应,
                本地响铃,
                回复响应,
               本地响铃回复响应
        };
#endif

const char *gSubMenu_PTT_ID[] =
        {
//                "OFF",
//                "UP CODE",
//                "DOWN CODE",
//                "UP+DOWN\nCODE",
//                "APOLLO\nQUINDAR"
                不发送,
                上线码,
                下线码,
                上线加下线码,
                Quindar码
        };



const char gSubMenu_ROGER[][13] =
        {
//                "OFF",
//                "ROGER",
//                "MDC"

                关闭,
                ROGER尾音,
                MDC尾音,
                MDC首音,
        MDC首尾音,
                MDC首音加ROGER
        };

const char gSubMenu_RESET[][6] =//4
        {
//                "VFO",
//                "ALL"
                除信道参数,
                全部参数
        };

const char *gSubMenu_F_LOCK[] =
        {
                "DEFAULT+\n137-174\n400-470",
                "FCC HAM\n144-148\n420-450",
                "CE HAM\n144-146\n430-440",
                "GB HAM\n144-148\n430-440",
                "137-174\n400-430",
                "137-174\n400-438",
//                "DISABLE\nALL",
//                "UNLOCK\nALL",
                禁用全部,
                解锁全部,
        };

const char gSubMenu_BACKLIGHT[][5] =//7
        {
//                "OFF",
//                "5 sec",
//                "10 sec",
//                "20 sec",
//                "1 min",
//                "2 min",
//                "4 min",
//                "ON"
                关闭,
                五秒,
                十秒,
                二十秒,
                一分,
                两分,
                四分,
                开启

        };

const char gSubMenu_RX_TX[][7] =//6
        {
//                "OFF",
//                "TX",
//                "RX",
//                "TX/RX"
                关闭,
                发送时,
                接收时,
                发送接收时
        };

#ifdef ENABLE_AM_FIX_TEST1
const char gSubMenu_AM_fix_test1[][8] =
{
    "LNA-S 0",
    "LNA-S 1",
    "LNA-S 2",
    "LNA-S 3"
};
#endif



const char gSubMenu_BATTYP[][8] =
        {
                "1600mAh",
                "2200mAh"
        };

const char gSubMenu_SCRAMBLER[][7] =
        {
//                "OFF",
                关闭,

                "2600Hz",
                "2700Hz",
                "2800Hz",
                "2900Hz",
                "3000Hz",
                "3100Hz",
                "3200Hz",
                "3300Hz",
                "3400Hz",
                "3500Hz"
        };


bool gIsInSubMenu;
uint8_t gMenuCursor;

int UI_MENU_GetCurrentMenuId() {
    if (gMenuCursor < ARRAY_SIZE(MenuList))
        return MenuList[gMenuCursor].menu_id;
    else
        return MenuList[ARRAY_SIZE(MenuList) - 1].menu_id;
}

uint8_t UI_MENU_GetMenuIdx(uint8_t id) {
    for (uint8_t i = 0; i < ARRAY_SIZE(MenuList); i++)
        if (MenuList[i].menu_id == id)
            return i;
    return 0;
}

int32_t gSubMenuSelection;

// edit box
char edit_original[17]; // a copy of the text before editing so that we can easily test for changes/difference
char edit[17];
int edit_index;


void UI_DisplayMenu(void) {
    const unsigned int menu_list_width = 6; // max no. of characters on the menu list (left side)
    const unsigned int menu_item_x1 = (8 * menu_list_width) ;//+ 2;
    const unsigned int menu_item_x2 = LCD_WIDTH - 1;
    unsigned int i;
    char String[64];  // bigger cuz we can now do multi-line in one string (use '\n' char)
#ifdef ENABLE_DTMF_CALLING
    char               Contact[16];
#endif

    // clear the screen buffer
    memset(gFrameBuffer, 0, sizeof(gFrameBuffer));

#if 1
    // original menu layout



    // invert the current menu list item pixels反转当前菜单项的像素值 :


    // draw vertical separating dotted line绘制垂直分隔的点线 :
//    for (i = 0; i < 7; i++)
//        gFrameBuffer[i][(8 * menu_list_width) + 1] = 0xAA;


    // draw the little sub-menu triangle marker绘制子菜单三角标志:
    //const void *BITMAP_CurrentIndicator = BITMAP_MARKER;

    if (gIsInSubMenu)
        memmove(gFrameBuffer[2] + 40, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));

    // draw the menu index number/count绘制菜单索引号/总数 :
    sprintf(String, "%2u/%u", 1 + gMenuCursor, gMenuListCount);
    UI_PrintStringSmall(String, 2, 0, 6);
//    UI_ShowChineseMenu();
    UI_ShowChineseMenu();

#else
    {	// new menu layout .. experimental & unfinished

        const int menu_index = gMenuCursor;  // current selected menu item
        i = 1;

        if (!gIsInSubMenu)
        {
            while (i < 2)
            {	// leading menu items - small text
                const int k = menu_index + i - 2;
                if (k < 0)
                    UI_PrintStringSmall(MenuList[gMenuListCount + k].name, 0, 0, i);  // wrap-a-round
                else
                if (k >= 0 && k < (int)gMenuListCount)
                    UI_PrintStringSmall(MenuList[k].name, 0, 0, i);
                i++;
            }

            // current menu item - keep big n fat
            if (menu_index >= 0 && menu_index < (int)gMenuListCount)
                UI_PrintStringSmall(MenuList[menu_index].name, 0, 0, 2);
            i++;

            while (i < 4)
            {	// trailing menu item - small text
                const int k = menu_index + i - 2;
                if (k >= 0 && k < (int)gMenuListCount)
                    UI_PrintStringSmall(MenuList[k].name, 0, 0, 1 + i);
                else
                if (k >= (int)gMenuListCount)
                    UI_PrintStringSmall(MenuList[gMenuListCount - k].name, 0, 0, 1 + i);  // wrap-a-round
                i++;
            }

            // draw the menu index number/count
            sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount);
            UI_PrintStringSmall(String, 2, 0, 6);
        }
        else
        if (menu_index >= 0 && menu_index < (int)gMenuListCount)
        {	// current menu item
            strcpy(String, MenuList[menu_index].name);
//			strcat(String, ":");
            UI_PrintStringSmall(String, 0, 0, 0);
//			UI_PrintStringSmall(String, 0, 0, 0);
        }
    }
#endif

    // **************

    memset(String, 0, sizeof(String));

    bool already_printed = false;
/* Brightness is set to max in some entries of this menu. Return it to the configured brightness
	   level the "next" time we enter here.I.e., when we move from one menu to another.
	   It also has to be set back to max when pressing the Exit key. */

    BACKLIGHT_TurnOn();
    switch (UI_MENU_GetCurrentMenuId()) {
        case MENU_SQL:
            sprintf(String, "%d", gSubMenuSelection);
            break;

        case MENU_MIC: {    // display the mic gain in actual dB rather than just an index number
            const uint8_t mic = gMicGain_dB2[gSubMenuSelection];
            sprintf(String, "+%u.%01udB", mic / 2, mic % 2);
        }
            break;

#ifdef ENABLE_AUDIO_BAR
//            case MENU_MIC_BAR:
//                strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
//                break;
#endif

        case MENU_STEP: {
            uint16_t step = gStepFrequencyTable[FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection)];
            sprintf(String, "%d.%02ukHz", step / 100, step % 100);
            break;
        }

//        case MENU_TXP:
//            strncpy(String, gSubMenu_TXP[gSubMenuSelection], sizeof(gSubMenu_TXP[gSubMenuSelection]));
//            String[sizeof(gSubMenu_TXP[gSubMenuSelection])] = '\0';
//
//
//            break;

        case MENU_R_DCS:
        case MENU_T_DCS:
            if (gSubMenuSelection == 0)
                //translate
#ifdef test
                  strcpy(String, "OFF");

#else
                strcpy(String, 关闭);

#endif

            else if (gSubMenuSelection < 105)
                sprintf(String, "D%03oN", DCS_Options[gSubMenuSelection - 1]);
            else
                sprintf(String, "D%03oI", DCS_Options[gSubMenuSelection - 105]);
            break;

        case MENU_R_CTCS:
        case MENU_T_CTCS: {
            if (gSubMenuSelection == 0)
               // translate
#ifdef test
                    strcpy(String, "OFF");

#else
            //关闭
                strcpy(String, 关闭);

#endif

            else
                sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10,
                        CTCSS_Options[gSubMenuSelection - 1] % 10);
            break;
        }

        case MENU_SFT_D:
            strncpy(String, gSubMenu_SFT_D[gSubMenuSelection] , sizeof( gSubMenu_SFT_D[gSubMenuSelection] ));
            String[sizeof( gSubMenu_SFT_D[gSubMenuSelection])] = '\0';
            break;

        case MENU_OFFSET:
            if (!gIsInSubMenu || gInputBoxIndex == 0) {
                sprintf(String, "%3d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000);
                UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);
            } else {
                const char *ascii = INPUTBOX_GetAscii();
                sprintf(String, "%.3s.%.3s  ", ascii, ascii + 3);
                UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);
            }

            UI_PrintStringSmall("MHz", menu_item_x1, menu_item_x2, 4);

            already_printed = true;
            break;

//        case MENU_W_N:
//
//            strcpy(String, gSubMenu_W_N[gSubMenuSelection]);
//            break;
   
        case MENU_SCR:
            strcpy(String, gSubMenu_SCRAMBLER[gSubMenuSelection]);
       
#if 1
          //  if (gSubMenuSelection > 0 && gSetting_ScrambleEnable)
            if (gSubMenuSelection > 0 )
                BK4819_EnableScramble(gSubMenuSelection - 1);
            else
                BK4819_DisableScramble();
#endif
            break;



        case MENU_ABR:
            strcpy(String, gSubMenu_BACKLIGHT[gSubMenuSelection]);
            
            
//            BACKLIGHT_SetBrightness(-1);
            break;

       // case MENU_ABR_MIN:
        case MENU_ABR_MAX:
            sprintf(String, "%d", gSubMenuSelection);
            if (gIsInSubMenu)
                BACKLIGHT_SetBrightness(gSubMenuSelection);
//            else
//                BACKLIGHT_SetBrightness(-1);
            break;

//        case MENU_AM:
//            strcpy(String, gModulationStr[gSubMenuSelection]);
//
//            break;

#ifdef ENABLE_AM_FIX_TEST1
            case MENU_AM_FIX_TEST1:
                strcpy(String, gSubMenu_AM_fix_test1[gSubMenuSelection]);
//				gSetting_AM_fix = gSubMenuSelection;
                break;
#endif



        case MENU_COMPAND:
            strcpy(String, gSubMenu_RX_TX[gSubMenuSelection]);


            break;

#ifdef ENABLE_AM_FIX
            case MENU_AM_FIX:
#endif
        case MENU_BCL:
   //     case MENU_BEEP:
//        case MENU_S_ADD1:
//        case MENU_S_ADD2:
        case MENU_STE:
        case MENU_D_ST:
#ifdef ENABLE_DTMF_CALLING
       // case MENU_D_DCD:
#endif
        case MENU_D_LIVE_DEC:
#ifdef ENABLE_NOAA
            case MENU_NOAA_S:
#endif
//        case MENU_350TX:
//        case MENU_200TX:
//        case MENU_500TX:
//        case MENU_350EN:
                       strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);

            break;
//        case MENU_SCREN:
//            strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
//
//
//            break;

        case MENU_MEM_CH:
        case MENU_1_CALL:
        case MENU_DEL_CH: {
            const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 1);

            UI_GenerateChannelStringEx(String, valid, gSubMenuSelection);
            UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);

            if (valid && !gAskForConfirmation) {    // show the frequency so that the user knows the channels frequency
                const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
                sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000);
                UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 5);
            }

            already_printed = true;
            break;
        }
#ifdef ENABLE_MDC1200
//            case MENU_MDC_ID:
//            ///    char mdc_id_str[4];
//    sprintf(String, "%04X", gEeprom.MDC1200_ID); // %04X确保输出是4个字符长度的十六进制数
//          //  strcpy(String, id);
//            break;

        case MENU_MDC_ID:
        {
//            gIsInSubMenu
//            if (!gIsInSubMenu||(edit_index<0&&gIsInSubMenu)) {    // show the channel name
//                               //     sprintf(edit, "%04lX", gEeprom.MDC1200_ID); // %04X确保输出是4个字符长度的十六进制数
//                                      sprintf(String, "%04X", gEeprom.MDC1200_ID); // %04X确保输出是4个字符长度的十六进制数
//
//                        edit[0]=String[0];
//                        edit[1]=String[1];
//                        edit[2]=String[2];
//                        edit[3]=String[3];
//
//
//                UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 3);//4
            //}
//            else
                if(gIsInSubMenu){    // show the channel name being edited
//                   edit_index= edit_index<0?0:edit_index;
//                   			memmove(edit_original, edit, sizeof(edit_original));

                UI_PrintStringSmall(edit, menu_item_x1, menu_item_x2, 3);
                if (edit_index < 4)
                    UI_PrintStringSmall("^", menu_item_x1+(((menu_item_x2 - menu_item_x1) - (28)) + 1) / 2 + (7 * edit_index), 0, 4);  // show the cursor
            }else
                {
                   //     sprintf(edit, "%04lX", gEeprom.MDC1200_ID); // %04X确保输出是4个字符长度的十六进制数
                                      sprintf(String, "%04X", gEeprom.MDC1200_ID); // %04X确保输出是4个字符长度的十六进制数
            edit_index = -1;

                        edit[0]=String[0];
                        edit[1]=String[1];
                        edit[2]=String[2];
                        edit[3]=String[3];


                UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 3);//4
                }
            already_printed = true;
            break;
        }
#endif
        case MENU_MEM_NAME: {
            const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 1);

            UI_GenerateChannelStringEx(String, valid, gSubMenuSelection);
            UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);

            if (valid) {
                const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
                //bug way
                if (!gIsInSubMenu || edit_index < 0) {    // show the channel name
                    SETTINGS_FetchChannelName(String, gSubMenuSelection);
                    if (String[0] == 0)
                        strcpy(String, "--");
                    
                    UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 3);//4
                } else {    // show the channel name being edited
                    UI_PrintStringSmall(edit, menu_item_x1, 0, 3);
                    if (edit_index < 10)
                        UI_PrintStringSmall("^", menu_item_x1 + (7 * edit_index), 0, 4);  // show the cursor
                }

                if (!gAskForConfirmation) {    // show the frequency so that the user knows the channels frequency
                    sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000);
                    if (!gIsInSubMenu || edit_index < 0)
                        UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 5);
                    else
                        UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 5);
                }
            }

            already_printed = true;
            break;
        }

        case MENU_SAVE:
            strcpy(String, gSubMenu_SAVE[gSubMenuSelection]);
            
            
            break;

        case MENU_TDR:
            strcpy(String, gSubMenu_RXMode[gSubMenuSelection]);
            
            
            break;

        case MENU_TOT:
            strcpy(String, gSubMenu_TOT[gSubMenuSelection]);
            
            
            break;

#ifdef ENABLE_VOICE
            case MENU_VOICE:
                strcpy(String, gSubMenu_VOICE[gSubMenuSelection]);
                break;
#endif

        case MENU_SC_REV:


            strcpy(String, gSubMenu_SC_REV[gSubMenuSelection]);


            break;

        case MENU_MDF:


    strcpy(String, gSubMenu_MDF[gSubMenuSelection]);
            
            
            break;

        case MENU_RP_STE:
            if (gSubMenuSelection == 0)
//translate
#ifdef test
                   strcpy(String, "OFF");

#else
            //关闭
                strcpy(String, 关闭);

#endif


            else
                sprintf(String, "%d*100ms", gSubMenuSelection);
            break;

        case MENU_S_LIST:
            if (gSubMenuSelection < 2)

         //translate

#ifdef test
                   sprintf(String, "list %u", 1 + gSubMenuSelection);

#else  //!!列表
                sprintf(String, 列表" %u", 1 + gSubMenuSelection);

#endif

            else

#ifdef test
                  strcpy(String, "ALL");

#else
            //全部
            strcpy(String, 全部);

#endif
            break;

#ifdef ENABLE_ALARM
            case MENU_AL_MOD:
                sprintf(String, gSubMenu_AL_MOD[gSubMenuSelection]);
                break;
#endif
#ifdef ENABLE_DTMF_CALLING
        case MENU_ANI_ID:

            strcpy(String, gEeprom.ANI_DTMF_ID);
            break;
#endif

        case MENU_UPCODE:

            sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_UP_CODE, gEeprom.DTMF_UP_CODE + 8);
            break;

        case MENU_DWCODE:
            sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_DOWN_CODE, gEeprom.DTMF_DOWN_CODE + 8);
            break;
#ifdef ENABLE_DTMF_CALLING
        case MENU_D_RSP:
            strcpy(String, gSubMenu_D_RSP[gSubMenuSelection]);
            
            
            break;

        case MENU_D_HOLD:
            sprintf(String, "%ds", gSubMenuSelection);
            break;
#endif
        case MENU_D_PRE:
            sprintf(String, "%d*10ms", gSubMenuSelection);
            break;

        case MENU_PTT_ID:
            strcpy(String, gSubMenu_PTT_ID[gSubMenuSelection]);
            
            
            break;

//        case MENU_BAT_TXT:
//            strcpy(String, gSubMenu_BAT_TXT[gSubMenuSelection]);
//
//
//            break;
#ifdef ENABLE_DTMF_CALLING
        case MENU_D_LIST:
            gIsDtmfContactValid = DTMF_GetContact((int) gSubMenuSelection - 1, Contact);
            if (!gIsDtmfContactValid)
                strcpy(String, "NULL");
            else
                memcpy(String, Contact, 8);
            break;
#endif
//        case MENU_PONMSG:
//            strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
//
//
//            break;

        case MENU_ROGER:
            strcpy(String, gSubMenu_ROGER[gSubMenuSelection]);
            
            
            break;

//        case MENU_VOL:
//            sprintf(String, "%u.%02uV\n%u%%",
//                    gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100,
//                    BATTERY_VoltsToPercent(gBatteryVoltageAverage));
//            break;

        case MENU_RESET:
            strcpy(String, gSubMenu_RESET[gSubMenuSelection]);
            
            
            break;

        case MENU_F_LOCK:
//            if (!gIsInSubMenu && gUnlockAllTxConfCnt > 0&& gUnlockAllTxConfCnt < 10)
//                strcpy(String, "READ\nMANUAL");
//
//            else
                strcpy(String, gSubMenu_F_LOCK[gSubMenuSelection]);
            
            
            break;

#ifdef ENABLE_F_CAL_MENU
            case MENU_F_CALI:
                {
                    const uint32_t value   = 22656 + gSubMenuSelection;
                    const uint32_t xtal_Hz = (0x4f0000u + value) * 5;

                    writeXtalFreqCal(gSubMenuSelection, false);

                    sprintf(String, "%d\n%u.%06u\nMHz",
                        gSubMenuSelection,
                        xtal_Hz / 1000000, xtal_Hz % 1000000);
                }
                break;
#endif

        case MENU_BATCAL: {
            const uint16_t vol = (uint32_t) gBatteryVoltageAverage * gBatteryCalibration[3] / gSubMenuSelection;
            sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection);
            break;
        }

        case MENU_BATTYP:
            strcpy(String, gSubMenu_BATTYP[gSubMenuSelection]);

            break;

//        case MENU_F1SHRT:
//        case MENU_F1LONG:
//        case MENU_F2SHRT:
//        case MENU_F2LONG:
//        case MENU_MLONG:
//            strcpy(String, gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].name);
//            break;

    }

    if (!already_printed) {    // we now do multi-line text in a single string

        unsigned int y;
        unsigned int lines = 1;
        unsigned int len = strlen(String);
        bool small = false;

        if (len > 0) {
            // count number of lines
            for (i = 0; i < len; i++) {
                if (String[i] == '\n' && i < (len - 1)) {    // found new line char
                    lines+=1;
                    String[i] = 0;  // null terminate the line
                }
            }

            if (lines > 3) {    // use small text
                small = true;
                if (lines > 7)
                    lines = 7;
            }

            // center vertically'ish
            if (small)
                y = 3 - ((lines + 0) / 2);  // untested
            else
                y = 2 - ((lines + 0) / 2);

            // draw the text lines
            for (i = 0; i < len && lines > 0; lines--) {
                if (small)
                    UI_PrintStringSmall(String + i, menu_item_x1, menu_item_x2, y + 1);
                else
                    UI_PrintStringSmall(String + i, menu_item_x1, menu_item_x2, y + 1);

                // look for start of next line
                while (i < len && String[i] !=0&&String[i] !='\n')
                    i++;

                // hop over the null term char(s)
                while (i < len && (String[i] ==0||String[i] =='\n'))
                    i++;

                y += small ? 1 : 2;
            }
        }
    }

    if (UI_MENU_GetCurrentMenuId() == MENU_SLIST1 || UI_MENU_GetCurrentMenuId() == MENU_SLIST2) {
        i = (UI_MENU_GetCurrentMenuId() == MENU_SLIST1) ? 0 : 1;

//		if (gSubMenuSelection == 0xFF)
        if (gSubMenuSelection < 0)
            strcpy(String, "NULL");
        else
            UI_GenerateChannelStringEx(String, true, gSubMenuSelection);

//		if (gSubMenuSelection == 0xFF || !gEeprom.SCAN_LIST_ENABLED[i])
        if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i]) {
            // channel number
            UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);

            // channel name
            SETTINGS_FetchChannelName(String, gSubMenuSelection);
            if (String[0] == 0)
                strcpy(String, "--");
            UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 4);
        } else {
            // channel number
            UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);

            // channel name
            SETTINGS_FetchChannelName(String, gSubMenuSelection);
            if (String[0] == 0)
                strcpy(String, "--");
            UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 4);

            if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i])) {
                sprintf(String, "PRI1:%u", gEeprom.SCANLIST_PRIORITY_CH1[i] + 1);
                UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 4);
            }

            if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i])) {
                sprintf(String, "PRI2:%u", gEeprom.SCANLIST_PRIORITY_CH2[i] + 1);
                UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 5);
            }
        }
    }

    if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
        UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
        UI_MENU_GetCurrentMenuId() == MENU_1_CALL) {    // display the channel name
        char s[11];
        SETTINGS_FetchChannelName(s, gSubMenuSelection);
        if (s[0] == 0)
            strcpy(s, "--");
        UI_PrintStringSmall(s, menu_item_x1, menu_item_x2, 3);
    }

    if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan)
        //扫描
        UI_PrintStringSmall(扫描, menu_item_x1, menu_item_x2, 5);

//
//    if (UI_MENU_GetCurrentMenuId() == MENU_UPCODE)
//        if (strlen(gEeprom.DTMF_UP_CODE) > 12)
//            UI_PrintStringSmall(gEeprom.DTMF_UP_CODE + 12, menu_item_x1, menu_item_x2, 5);
//
//    if (UI_MENU_GetCurrentMenuId() == MENU_DWCODE)
//        if (strlen(gEeprom.DTMF_DOWN_CODE) > 12)
//            UI_PrintStringSmall(gEeprom.DTMF_DOWN_CODE + 12, menu_item_x1, menu_item_x2, 5);
#ifdef ENABLE_DTMF_CALLING
    if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid) {
        Contact[11] = 0;
        memcpy(&gDTMF_ID, Contact + 8, 4);
        sprintf(String, "ID:%s", Contact + 8);
        UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 5);
    }
#endif
    if (UI_MENU_GetCurrentMenuId() == MENU_R_CTCS ||
        UI_MENU_GetCurrentMenuId() == MENU_T_CTCS ||
        UI_MENU_GetCurrentMenuId() == MENU_R_DCS ||
            UI_MENU_GetCurrentMenuId() == MENU_T_DCS
#ifdef ENABLE_DTMF_CALLING
        || UI_MENU_GetCurrentMenuId() == MENU_D_LIST
#endif
            )

    {

        sprintf(String, "%2d", gSubMenuSelection);
        UI_PrintStringSmall(String, 105, 0, 1);//small
    }

    if ((UI_MENU_GetCurrentMenuId() == MENU_RESET ||
         UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
         UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME ||
            UI_MENU_GetCurrentMenuId() == MENU_MDC_ID||
         UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation) {    // display confirmation
        strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!");
        UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 5);
        gRequestSaveSettings  = 1;

    }
//    for (int i = 0; i < 128; i++) {
//        // Set the 7th and 8th positions to 1, keep others unchanged
//        gFrameBuffer[1][i] |= (1 << 7)|(1<<6) ;
//
//    }

    ST7565_BlitFullScreen();
}

//


void UI_ShowChineseMenu() {
  //  return;
    uint8_t cnt_char = 0;

    uint8_t size_menu = 0;
    uint8_t cnt_menu=0;
    for ( cnt_menu = 0; cnt_menu < 7 && MenuList[gMenuCursor].name[cnt_menu] != 0; cnt_menu++) {

            if(is_chn(MenuList[gMenuCursor].name[cnt_menu])!=255)//中文
                size_menu+=12;
            else//英文
                size_menu+=7;

    }
    cnt_char = 0;
    if (size_menu < 48)cnt_char = (48 - size_menu ) / 2;
    menu_set_flag=1;
    UI_PrintStringSmall(MenuList[gMenuCursor].name, (cnt_char), 0, 0);
//
//    for (uint8_t i = 0; i < cnt_menu; i++) {
//        uint8_t num_solve=is_chn(MenuList[gMenuCursor].name[i]);
//        if(num_solve==255)//数字/字母
//        {
//            char tmp[2]={0};
//            tmp[0]=MenuList[gMenuCursor].name[i];
//            UI_PrintStringSmall((const char *)tmp, (cnt_char), 0, 0);
//            cnt_char += 7;
//        } else  {
//
//
//            UI_PrintChineseChar(num_solve, cnt_char, 0);
//
//            cnt_char += 13;
//        }
//
//    }

}