#include <stdio.h>
#include <string.h>

#define _UNOFFICIAL

#define MSEC 1000

#define LED_OFF   fputs("7,1\n", f_led)
#define LED_ON    fputs("7,2\n", f_led)
#define LED_BLINK fputs("7,3\n", f_led)

#define T_DIT 60000/(50*wpm) * MSEC

#define DAH	3
/* Time between... */
#define SIGN	1
#define LETTER	DAH
#define WORD	7

char* morsecode[] = {
			/* '.' is a dit, '-' is a dah, everything else is a pause of one dit */

			/* letters */
			"A" ".-",
			"B" "-...",
			"C" "-.-.",
			"D" "-..",
			"E" ".",
			"F" "..-.",
			"G" "--.",
			"H" "....",
			"I" "..",
			"J" ".---",
			"K" "-.-",
			"L" ".-..",
			"M" "--",
			"N" "-.",
			"O" "---",
			"P" ".--.",
			"Q" "--.-",
			"R" ".-.",
			"S" "...",
			"T" "-",
			"U" "..-",
			"V" "...-",
			"W" ".--",
			"X" "-..-",
			"Y" "-.--",
			"Z" "--..",

			/* numbers */
			"0" "-----",
			"1" ".----",
			"2" "..---",
			"3" "...--",
			"4" "....-",
			"5" ".....",
			"6" "-....",
			"7" "--...",
			"8" "---..",
			"9" "----.",

			/* punctuation */
			"." ".-.-.-",
			"," "--..--",
			"?" "..--..",
			"\'" ".----.",
			"/" "-..-.",
			"&" ". ...",
			":" "---...",
			";" "-.-.-.",
			"=" "-...-",
			"-" "-....-",
			"$" "...-..-",
			"\"" ".-..-.",
			"@" ".--.-.",
#ifdef _UNOFFICIAL
			"!" "-.-.--",
			"(" "-.--.",
			")" "-.--.-"
#else
			"(" "-.--.-",
			")" "-.--.-"
#endif
};

int morse(char s[]);
void strmorse(char s[]);

FILE* f_led;
int wpm = 20;

int main(int argc, char* argv[])
{
	int i;

	if (argc < 2) {
		printf("Usage: %s [words-per-minute] string\n", argv[0]);
		return -1;
	}
	
	if (argc > 2 && isdigit(*argv[1])) {
		wpm = atoi(argv[1]);
		i = 2;
	} else
		i = 1;

	f_led = fopen("/var/led", "w");
	setvbuf(f_led, NULL, _IONBF, BUFSIZ);

	strmorse(argv[i]);
	putchar('\n');

	return 0;
}

int morse(char s[])
{
	int i, n;

	for (i = 1; s[i] != '\0'; i++) {
		switch (s[i]) {
			case '.':
				LED_ON;
				usleep(T_DIT);
				break;
			case '-':
				LED_ON;
				usleep(DAH*T_DIT);
				break;
			default:
				usleep(T_DIT);
		}
		LED_OFF;
		if (s[i+1] != '\0')
			usleep(SIGN*T_DIT);
	}
	
	return i-1;
}
	

void strmorse(char s[])
{
	int c, i, j, in_word;

	for (i = 0; s[i] != '\0'; i++) {
		if (isblank(s[i]))
			in_word = 1;
		else {
			if (in_word) {
				usleep((WORD-LETTER)*T_DIT);
				in_word = 0;
			}

			c = toupper(s[i]);
		
			/* find the morse code */
			for (j = sizeof(morsecode)/sizeof(char*)-1; j >= 0 && morsecode[j][0] != c; j--)
				;

			if (i >= 0) {
				morse(morsecode[j]);
				if (s[i+1] != '\0') {
					usleep(LETTER*T_DIT);
				}
			} else
				printf("unknown character '%c'\n", s[i]);
		}
	}
}

