#define M_DASH_THRESHOLD        0.140
#define M_SPACE_THRESHOLD       0.300

U8 *morse_list =
"A.-\0"
"B-...\0"
"C-.-.\0"
"D-..\0"
"E.\0"
"F..-.\0"
"G--.\0"
"H....\0"
"I..\0"
"J.---\0"
"K-.-\0"
"L.-..\0"
"M--\0"
"N-.\0"
"O---\0"
"P.--.\0"
"Q--.-\0"
"R.-.\0"
"S...\0"
"T-\0"
"U..-\0"
"V...-\0"
"W.--\0"
"X-..-\0"
"Y-.--\0"
"Z--..\0"

"1.----\0"
"2..---\0"
"3...--\0"
"4....-\0"
"5.....\0"
"6-....\0"
"7--...\0"
"8---..\0"
"9----.\0"
"0-----\0"

"/-..-.\0"
"+.-.-.\0"
"..-.-.-\0"
",--..--\0"
"?..--..\0"
"(-.--.\0"
")-.--.-\0"
"--....-\0"
"\".-..-.\0"
"_..--.-\0"
"'.----.\0"
":---...\0"
";-.-.-.\0"
"=-...-\0";

U0 MorseTable()
{
        U8 *st;
        I64 i = 0;

        for (i = 0; i < 13; i++ )
        {
                if (st = ListSub(i ,morse_list))
                        "$RED$%C$FG$ %-7s ", *st, st + 1;
                if (st = ListSub(i + 13, morse_list))
                        "$RED$%C$FG$ %-7s ", *st, st + 1;
                if (st = ListSub(i + 26, morse_list))
                        "$RED$%C$FG$ %-7s ", *st, st + 1;
                if (st = ListSub(i + 39, morse_list))
                        "$RED$%C$FG$ %-7s ", *st, st + 1;
                '\n';
        }
        '\n';
}

F64  m_start, m_end, dt_down, dt_up;
Bool space_sent;

U8 *MorseTimes(CDoc *, CDocEntry *, CTask *mem_task)
{
        U8 *st = MAlloc(64, mem_task);

        StrPrint(st, "Down:%10.6f Up:%10.6f", dt_down, dt_up);

        return st;
}

I64 MorseWaitKey()
{
        I64 ch;
        F64 dt;

        while (TRUE)
        {
                if (m_start)
                {
                        MessageGet(NULL, NULL, 1 << MESSAGE_KEY_UP);
                        m_end = tS;
                        Sound;
                        dt_down = m_end - m_start;
                        m_start = 0;
                        space_sent = FALSE;
                        if (dt_down < M_DASH_THRESHOLD)
                                return '.';
                        else
                                return '-';
                }
                else
                {
                        if (!space_sent)
                        {
                                while (!MessageScan(&ch, NULL, 1 << MESSAGE_KEY_DOWN))
                                {
                                        dt = tS - m_end;
                                        if (dt >= M_SPACE_THRESHOLD)
                                        {
                                                space_sent = TRUE;
                                                return CH_SPACE;
                                        }
                                        Yield;
                                }
                        }
                        else
                                ch = CharGet(, FALSE);
                        m_start = tS;
                        Sound(74);
                        if (ch == CH_SHIFT_ESC || ch == CH_ESC)
                        {
                                '\n';
                                Sound;
                                throw; //exit program
                        }
                        dt_up = m_start - m_end;
                        if (!space_sent && dt_up >= M_SPACE_THRESHOLD)
                        {
                                space_sent = TRUE;
                                return CH_SPACE;
                        }
                }
        }
}

U0 Morse()
{
        CDocEntry *doc_e;
        I64 ch;
        U8 buf[8], *dst, *src;

        MorseTable;
        m_start = 0;
        m_end = tS;
        dt_down = 0;
        dt_up = 0;
        space_sent = TRUE;

        "$GREEN$";

        doc_e = DocPrint(DocPut, "$TX+TC,\" \"$");
        doc_e->tag_cb = &MorseTimes;

        "$FG$\n";

        dst = buf;
        while (TRUE)
        {
                ch = MorseWaitKey;
                if (ch == CH_SPACE)
                {
                        *dst = 0;
                        src = morse_list;
                        while (*src) {
                                if (!StrCompare(src + 1, buf))
                                {
                                        "$GREEN$%C$FG$", *src;
                                        break;
                                }
                                else
                                        src += StrLen(src) + 1;
                        }
                        '' CH_SPACE;
                        dst = buf;
                }
                else
                {
                        if (dst - buf < sizeof(buf) - 1)
                        {
                                '' ch;
                                *dst++ = ch;
                        }
                }
        }
        Sound;
}

Morse;