
#ifndef __LCDB_C
#define __LCDB_C

/************************************************
*** Функции для работы с дисплеем МЭЛТ МТ-12864А
***	функции высокого уровня
************************************************/

#include "font.h"
#include "LCD.h"
#include "LCD_b.h"

//--------------------------------------------------------------------------------------
//*** Функция для отображения одного символа на экране размером 6х8 пикселей (6 - ширина, 8 - высота)
//*** параметры:	Symbol - символ, который надо отобразить
//***				Crystal - кристалл LCD, на котором надо отобразить символ
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void PrintSymbol(uint8_t Symbol, uint8_t Address, uint8_t Method)
{
	uint32_t Offset= Symbol*6;
	if(Method==0)
	{
		WriteByte(Font_6x8_Data[Offset],Address);
		Address++;
		WriteByte(Font_6x8_Data[Offset+1],Address);
		Address++;	 
		WriteByte(Font_6x8_Data[Offset+2],Address);
		Address++;
		WriteByte(Font_6x8_Data[Offset+3],Address);
		Address++;
		WriteByte(Font_6x8_Data[Offset+4],Address);
		Address++;
		WriteByte(Font_6x8_Data[Offset+5],Address);
	}
	else
	{
		WriteByte(~Font_6x8_Data[Offset],Address);
		Address++;
		WriteByte(~Font_6x8_Data[Offset+1],Address);
		Address++;	 
		WriteByte(~Font_6x8_Data[Offset+2],Address);
		Address++;
		WriteByte(~Font_6x8_Data[Offset+3],Address);
		Address++;
		WriteByte(~Font_6x8_Data[Offset+4],Address);
		Address++;
		WriteByte(~Font_6x8_Data[Offset+5],Address);
	}
}
//--------------------------------------------------------------------------------------
//*** Функция для отображения константной строки на экране
//*** параметры:	Text - указатель на константную строку, которую надо вывести
//***				Page - страница ОЗУ LCD, на которой требуется отобразить текст
//***				Address - адрес, с которого необходимо выводить текст на LCD 
//*** возвращаемых значений нет
//*** в строке последний байт должен быть 0х00!
//--------------------------------------------------------------------------------------

void PrintConstText(uint8_t* String, uint8_t Page, uint8_t Address, uint8_t Method)
{
//используется страничное деление экрана!
	int LenWord, Length=0;
	uint8_t* ms;

	ClearPage(Page,First);
	ClearPage(Page,Second);
	
	SetPage(Page,First);
	SetPage(Page,Second);

	ms = String;
	while(*(ms++)!=0) Length++;

	for(LenWord=0;LenWord<Length;LenWord++,Address+=6)	PrintSymbol(String[LenWord],Address,Method);

}

//--------------------------------------------------------------------------------------
//*** Функция для отображения текста и вставки числа на экране (выводятся целые беззнаковые числа)
//*** параметры:	Text - указатель на строку, которую надо вывести
//***				Value - значение, которое необходимо отобразить на экране
//***				Page - страница ОЗУ LCD, на которой требуется отобразить текст
//***				Address - адрес, с которого необходимо выводить текст на LCD 
//***				Method - способ отображения текста на экране (на белом фоне или на темном фоне)
//***				ntn - система счисления, в которой выводить цифровую информацию
//*** возвращаемых значений нет
//*** в строке последний байт должен быть 0х00!
//--------------------------------------------------------------------------------------
void PrintText(uint8_t* String, uint32_t Value,uint8_t Page, uint8_t Address, uint8_t Method, notation ntn)
{
//используется страничное деление экрана!
	uint32_t LenWord=0, Length=0, PositionForInsert=0, Temp, ValNumOfChar, ptr;
	uint8_t NewStr[21], CharVal[33];
	uint8_t* ms;

//вычисляем длину строки
	ms = String;
	while(*(ms++)!=0) Length++;
	if(Length>21) Length = 21;

//вычисляем место вставки значения Value
	ms = String;
	while(LenWord++ < Length)
	{
		if(ms[LenWord]=='%')
		{
			PositionForInsert = LenWord;
			break;
		}
	}

//Переводим значение Value в массив символов
	DigitalToChar(&CharVal[0],Value,&ValNumOfChar,ntn);
	
//Формируем новую строку до вставки
	for(Temp=0;Temp<PositionForInsert;Temp++)	NewStr[Temp] = ms[Temp];
	
//Вычисляем длину сформированной новой строки вместе со вставкой Value
	if((ValNumOfChar+Temp)>21)
	{
		ptr=ValNumOfChar+Temp-21;	//номер элемента в массиве, с которого надо начинать вывод на экран
		//Делаем вставку массива символов Value в новую строку
  		for(LenWord=0;Temp<21;Temp++)	NewStr[Temp] = CharVal[ptr+LenWord++];
	}
	else
	{
		ValNumOfChar+=Temp;
		//Делаем вставку массива символов Value в новую строку
		for(LenWord=0;Temp<ValNumOfChar;Temp++)	NewStr[Temp] = CharVal[LenWord++];
	}

//Дописываем то, что осталось после вставки
	LenWord = Length - (PositionForInsert + 1);
	PositionForInsert++;
	if((Temp < 21)&&(LenWord!=0))
		for(;(Temp < 21)&&(LenWord!=0);Temp++,LenWord--)	NewStr[Temp] = ms[PositionForInsert++];
	
	SetPage(Page,First);
	SetPage(Page,Second);

	for(LenWord=0;LenWord<Temp;LenWord++)
	{
		PrintSymbol(NewStr[LenWord],Address,Method);
		Address += 6;
	}
}

//--------------------------------------------------------------------------------------
//*** Функция для перевода числа Val в массив символов, на который указывает MyStr
//*** параметры:	MyStr - указатель на строку, в которую будет помещен результат
//***				(массив должен содержать 32 символа)
//***				Value - значение, которое необходимо отобразить на экране
//***				Len - указатель, по которому будет находиться кол-во элементов в
//***				массиве (не включая терминальный 0)
//***				ntn - указывает, в какой системе счисления формировать массив данных
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void DigitalToChar(uint8_t* MyStr, uint32_t Val, uint32_t* Len, notation ntn)
{
	uint32_t i,f,Temp,j,non=0,div,num;
	uint8_t Arr[33];

//Переводим значение Val в строку символов (символы расположены в обратном порядке, Arr[0] - единицы, Arr[1] - десякти, и т.д.)
	if(ntn==dec)
	{
		div=10;
		num=10;
	}
	else if(ntn==oct)
	{
		div=8;
		num=11;
	}
	else if(ntn==bin)
	{
		div=2;
		num=32;
	}
	else
	{
		div=16;
		num=8;
	}

	for(Temp=0;Temp<num;Temp++)
	{
		i=Val/div;
		f=Val%div;
		if(f<10)	Arr[Temp]=0x30+f;
		else		Arr[Temp]=0x41+(f-10);
		Val=i;
		if(i==0)	//отбрасываем лишние нули
		{
			non=Temp;
			break;
		}
	}

//Начинаем формировать результирующий массив символов
	if(ntn==dec)
	{
		if(non==0)
		{
			MyStr[0] = Arr[0];
			MyStr[1] = 0;
			*Len = 1;
			return;
		}
		else
		{
			*Len = 0;
			j = non;
			for(Temp=0;Temp<=j;Temp++)
			{
				MyStr[Temp] = Arr[non--];
				(*Len)++;
			}
			MyStr[Temp] = 0;
			return;
		}
	}
	else if(ntn==oct)
	{
		if(non==0)
		{
			MyStr[0]=Arr[0];
			MyStr[1]=0;
			*Len=1;
			return;
		}
		else
		{
			*Len=0;
			j=non;
			for(Temp=0;Temp<=j;Temp++)
			{
				MyStr[Temp]=Arr[non--];
				(*Len)++;
			}
			MyStr[Temp]=0;
			return;
		}
	}
	else if(ntn==bin)
	{
		if(non==0)
		{
			MyStr[0]=Arr[0];
			MyStr[1]=0;
			*Len=1;
			return;
		}
		else
		{
			*Len=0;
			j=non;
			for(Temp=0;Temp<=j;Temp++)
			{
				MyStr[Temp]=Arr[non--];
				(*Len)++;
			}
			MyStr[Temp]=0;
			return;
		}
	}
	else
	{
		MyStr[0] = '0';
		MyStr[1] = 'x';
		
		if(non == 0)
		{	
			MyStr[2] = Arr[0];
			MyStr[3] = 0;
			*Len = 3;
			return;
		}

		*Len = 2;
		j = non;
		for(Temp=0;Temp<=j;Temp++)
		{
			MyStr[Temp+2] = Arr[non--];
			(*Len)++;
		}
		MyStr[Temp+2] = 0;
	}
}

//--------------------------------------------------------------------------------------
//*** Функция для вычисления длины строки символов
//*** параметры:	Str - указатель на строку, размер которой необходимо узнать
//*** возвращаемые значеня: кол-во байт, занимаемое строкой
//--------------------------------------------------------------------------------------
uint32_t StrLen(uint8_t* Str)
{
	uint8_t* ptr;
	uint32_t Len;

	ptr = Str;
	Len = 0;
	while(*(ptr++)!=0x00)	Len++;

	return Len;
}

#endif	//__LCDB_C
