#include <windows.h>
#include "tele.h"

// Текущее положение курсора
static int	nyCurrRow, nxCurrCol;

// Размер главного окна приложения в символах
static int	nyRows, nxCols;

// Размер символов
static int	nxCharSize, nyCharSize;


// ===================================================================
// Функция InitTTY
// ===================================================================
void InitTTY(HWND hwnd)
{
	HDC			hdc;				// индекс контекста устройства
	TEXTMETRIC	tiTextMetric;	// структура для записи метрик шрифта
	RECT			rcTTYWindow;	// размер окна

	// Определяем начальное положение курсора
	nyCurrRow = 0;	
	nxCurrCol = 0;

	// Получаем контекст отображения
	hdc = GetDC( hwnd );

	// Выбираем в контекст отображения шрифт OEM_FIXED_FONT
	SelectObject(hdc, GetStockObject(OEM_FIXED_FONT));

	// Заполняем структуру tiTextMetric информацией о метрике
   // шрифта, выбранного в контекст отображения
	GetTextMetrics(hdc, &tiTextMetric);

	// Освобождаем контекст
	ReleaseDC( hwnd, hdc );

	// Запоминаем среднее значение ширины символов
	nxCharSize = tiTextMetric.tmAveCharWidth;

	// Запоминаем значение высоты символов с учетом
   // межстрочного интервала
	nyCharSize = tiTextMetric.tmHeight +
					 tiTextMetric.tmExternalLeading;

	// Определяем текущее размеры окна
	GetClientRect(hwnd, &rcTTYWindow);

	// Определяем количество строк, помещающихся в окне
	nyRows = (rcTTYWindow.bottom - rcTTYWindow.top) / nyCharSize;

	// Определяем количество символов, помещающихся в строке окне
	nxCols = (rcTTYWindow.right - rcTTYWindow.left) / nxCharSize;

	return;
}



// ===================================================================
// Функция WriteTTY
// ===================================================================
void WriteTTY( LPSTR lpOutString, HWND hwnd, COLORREF rgbColor )
{
	LPSTR	lpCurrChar;	// рабочий указатель  
	HDC	hdc;			// индекс контекста устройства

	// Получаем контекст отображения
	hdc = GetDC( hwnd );

	// Выбираем в контекст отображения шрифт OEM_FIXED_FONT
	SelectObject( hdc, GetStockObject(OEM_FIXED_FONT));

	// Устанавливаем цвет текста
	SetTextColor(hdc, rgbColor);

	// Устанавливаем цвет фона текста соответствующий цвету окна
	SetBkColor(hdc, GetSysColor(COLOR_WINDOW));

	// Устанавливаем режим вывода текста
	SetBkMode(hdc, OPAQUE);

	// Выключаем курсор
	HideCaret( hwnd );

	// Отображаем строку lpOutString в окне
	for ( lpCurrChar = lpOutString; *lpCurrChar; lpCurrChar++ )
	{
		switch ( *lpCurrChar )
		{
			// Возвратить курсор на одну позицию назад
			case ASCII_BACK:
         {
				if(nxCurrCol)
					nxCurrCol--;

				break;
         }

			// Перевести курсор в начало текущей строки
			case ASCII_CR:
         {
				nxCurrCol = 0;
				break;
         }

			// Перевести курсор на новую строку
			case ASCII_LF:
         {
				nyCurrRow++;

				// При необходимости выполняем вертикалиную свертку окна
				if ( nyCurrRow == ( nyRows - 1 ) )
				{
					ValidateRect( hwnd, NULL );
					ScrollWindow( hwnd, 0, -nyCharSize, NULL, NULL );

               // Передаем сообщение WM_PAINT
					UpdateWindow( hwnd );

               // Изменяем текущее положение курсора
					nyCurrRow = nyRows - 2;
				}
				break;
         }

			// Подать звуковой сигнал
			case ASCII_BELL:
         {
				MessageBeep(MB_OK);
				break;
         }

			default:
         {
				// Отображаем очередной символ из строки lpOutString в текущей
            // позиции окна
				TextOut( hdc, nxCurrCol * nxCharSize, nyCurrRow * nyCharSize,
							lpCurrChar, 1 );

				// Смещаем курсор вправо
				nxCurrCol++;

				// При необходимости переходим на следующую строку
				if ( nxCurrCol == ( nxCols - 1 ) )
				{
					nxCurrCol = 0;
					nyCurrRow++;

					// Если надо выполняем вертикальную свертку экрана
					if ( nyCurrRow == ( nyRows - 1 ) )
					{
						ValidateRect( hwnd, NULL );
						ScrollWindow( hwnd, 0, -nyCharSize, NULL, NULL );
						UpdateWindow( hwnd );
						nyCurrRow = nyRows - 2;
					}
				}
				break;
         }
		}
	}

	// Перемещаем курсор в новую позиицию
	SetCaretPos( nxCurrCol * nxCharSize, nyCurrRow * nyCharSize );

	// Отображаем курсор
	ShowCaret( hwnd );

	// Освобождаем контекст
	ReleaseDC( hwnd, hdc );

	return;
}

// ===================================================================
// Функция SetFocusTTY
// ===================================================================
void SetFocusTTY(HWND hwnd)
{
   // Создаем текстовый курсор
	CreateCaret( hwnd, NULL, nxCharSize, nyCharSize );

	// Перемещаем курсор в текущую позиицию
	SetCaretPos( nxCurrCol * nxCharSize, nyCurrRow * nyCharSize );

	// Отображаем курсор
	ShowCaret( hwnd );

	return;
}

// ===================================================================
// Функция KillFocusTTY
// ===================================================================
void KillFocusTTY(HWND hwnd)
{
	// Выключаем курсор
	HideCaret(hwnd);

	// Удаляем курсор
	DestroyCaret();

	return;
}
