
#ifndef	__LCDGRAPHIC_C
#define __LCDGRAPHIC_C

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

//--------------------------------------------------------------------------------------
//*** Функция для отображения прямой линии на экране 
//*** параметры:	X0 - координата х начала линии (0...127)
//***				Y0 - координата y начала линии (0...63)
//*** 				X1 - координата х окончания линии (0...127)
//***				Y1 - координата y окончания линии (0...63)
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void DrawLine(int x0, int y0, int x1, int y1)
{
	unsigned char Length,Height;
	int Xc,Yc;
	
	if(x1 > x0) 	Length = x1 - x0;
	else			Length = x0 - x1;
	if(Length>128)	Length = 128;

	if(y1 > y0)		Height = y1 - y0;
	else 			Height = y0 - y1;
	if(Height>63)	Height = 64;

	if(Length != 0)				//если длина не равна 0
	{
		if(Height != 0)			//если высота не равнв 0
		{
			if(Length>=Height)	//если длина больше высоты линии, то
			{
				if(x0<x1)
				{
					if(y0<y1)			//(x0<x1)&(y0<y1)
					{
						Yc = y0;
						for(Xc=x0;Xc<=x1;)
						{
							PutPixel(Xc,Yc);
							Xc++;
							Yc = y0 + (Xc-x0)*Height/Length;
						}
					}
					else				//(x0<x1)&(y0>y1)
					{
						Yc = y0;
						for(Xc=x0;Xc<=x1;)
						{
							PutPixel(Xc,Yc);
							Xc++;
							Yc = y0 - (Xc-x0)*Height/Length;
						}
					}
					
				}
				else
				{
					if(y0<y1)			//(x0>x1)&(y0<y1)
					{
						Yc = y1;
						for(Xc=x1;Xc<=x0;)
						{
							PutPixel(Xc,Yc);
							Xc++;
							Yc = y0 + (x0-Xc)*Height/Length;
						}
					}
					else				//(x0>x1)&(y0>y1)
					{
						Yc = y1;
						for(Xc=x1;Xc<=x0;)
						{
							PutPixel(Xc,Yc);
							Xc++;
							Yc = y0 - (x0-Xc)*Height/Length;
						}
					}
				}
			}
			else				//если высота больше длина линии, то
			{
				if(y0<y1)				
				{
					if(x0<x1)			//(y0<y1)&(x0<x1)
					{
						Xc = x0;
						for(Yc=y0;Yc<=y1;)
						{
							PutPixel(Xc,Yc);
							Yc++;
							Xc = x0 + (Yc-y0)*Length/Height;
						}
					}
					else				//(y0<y1)&(x0>x1)
					{
						Xc = x0;
						for(Yc=y0;Yc<=y1;)
						{
							PutPixel(Xc,Yc);
							Yc++;
							Xc = x0 - (Yc-y0)*Length/Height;
						}
					}

				}
				else
				{
					if(x0<x1)			//(y0>y1)&(x0<x1)
					{
						Xc = x1;
						for(Yc=y1;Yc<=y0;)
						{
							PutPixel(Xc,Yc);
							Yc++;
							Xc = x0 + (y0-Yc)*Length/Height;
						}
					}
					else				//(y0>y1)&(x0>x1)
					{
						Xc = x1;
						for(Yc=y1;Yc<=y0;)
						{
							PutPixel(Xc,Yc);
							Yc++;
							Xc = x0 - (y0-Yc)*Length/Height;
						}
					}
				}
			}
		}
		else					//если высота равнв 0 (рисуем горизонтальную линию)
		{
			DrawHorizontalLine(x0,x1,y0);
		}
	}
	else 						//если длина равна 0
	{
		if(Height != 0)			//если высота не равнв 0, рисуем вертикальную линию
		{
			DrawVerticalLine(x0, y0, y1);
		}
		else					//если высота равнв 0, рисуем пиксель
		{
			PutPixel(x0,y0);
		}
	}

}
//--------------------------------------------------------------------------------------
//*** Функция для отображения одного пиксела на экране 
//*** параметры:	X0 - координата х отображаемого пиксела	(0...127)
//***				Y0 - координата y отображаемого пиксела	(0...63)
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void PutPixel(uint8_t X0,uint8_t Y0)
{
	uint8_t Page,i;
	Page = GetPage(Y0);
	i = ReadByte(Page,X0);
	Y0 = BitSet(Y0);	//в Y0 установлен бит, который необходимо отобразить на дисплее, остальные биты установлены в 0.
	i |= Y0;
	WriteByte(i,X0);	//записываем в ОЗУ LCD
}
//--------------------------------------------------------------------------------------
//*** Функция для отображения вертикальной линии
//*** параметры:	X0 - координата x вертикальной линии (0...127)
//***				Y0 - начало линии по координате y (0...63)
//***				Y1 - окончание линии по координате y (0...63)
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void DrawVerticalLine(uint8_t X0, uint8_t Y0, uint8_t Y1)
{
	uint8_t Temp;
	if(Y0>Y1)
	{
		Temp = Y1;
		Y1 = Y0;
		Y0 = Temp;
	}
	for(;Y0<=Y1;Y0++)
	{
		PutPixel(X0,Y0);
	}
}
//--------------------------------------------------------------------------------------
//*** Функция для отображения горизонтальной линии
//*** параметры:	X0 - начальная координата x горизонтальной линии (0...127)
//***				X1 - конечная координата х горизонтальной линии (0...127)
//***				Y0 - координата y горизонтальной линии (0...63)
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void DrawHorizontalLine(uint8_t X0, uint8_t X1, uint8_t Y0)
{
	uint8_t Temp;
	if(X0>X1)
	{
		Temp = X1;
		X1 = X0;
		X0 = Temp;
	}
	for(;X0<=X1;X0++)
	{
		PutPixel(X0,Y0);
	}
}

//--------------------------------------------------------------------------------------
//*** Функция для отображения прямоугольника (незаштрихованный)
//*** параметры:	X0 - координата x левого верхнего угла прямоугольника (0...127)
//***				Y0 - координата у левого верхнего угла прямоугольника (0...63)
//***				X1 - координата x правого нижнего угла прямоугольника (0...127)
//***				Y1 - координата у правого нижнего угла прямоугольника (0...63)
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void DrawRect(uint8_t X0, uint8_t Y0, uint8_t X1, uint8_t Y1)
{
	if(X0-X1==0)
	{
		DrawVerticalLine(X1, Y0, Y1);
		return;
	}
	if(Y0-Y1==0)
	{
		DrawHorizontalLine(X0, X1, Y0);
		return;
	}
	DrawHorizontalLine(X0, X1, Y0);
	DrawVerticalLine(X1, Y0+1, Y1);
	DrawHorizontalLine(X0, X1-1, Y1);
	DrawVerticalLine(X0, Y0+1, Y1-1);
}

//--------------------------------------------------------------------------------------
//*** Функция для отображения прямоугольника (незаштрихованный)
//*** параметры:	X0 - координата x первого угла треугольника (0...127)
//***				Y0 - координата у первого угла треугольника (0...63)
//***				X1 - координата x второго угла треугольника (0...127)
//***				Y1 - координата у второго угла треугольника (0...63)
//***				X2 - координата x третьего угла треугольника (0...127)
//***				Y2 - координата у третьего угла треугольника (0...63)
//*** возвращаемых значений нет
//--------------------------------------------------------------------------------------
void DrawTriangle(uint8_t X0, uint8_t Y0, uint8_t X1, uint8_t Y1, uint8_t X2, uint8_t Y2)
{
	DrawLine(X0,Y0,X1,Y1);
	DrawLine(X1,Y1,X2,Y2);
	DrawLine(X0,Y0,X2,Y2);	
}

//--------------------------------------------------------------------------------------
//*** устанавливается один из бит в регистре, который соответствует передаваемой координате
//*** и будет записан в ОЗУ дисплея (функция не учитывает номера страницы, поэтому перед
//*** ней должна вызываться предыдущая функция)
//--------------------------------------------------------------------------------------
uint8_t BitSet(uint8_t Val)
{
	return (1<<(Val%8));
}
//--------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------
//*** функция возвращает номер страницы, на которой находится координата, передаваемая в кач. параметра
//--------------------------------------------------------------------------------------
uint8_t GetPage(uint8_t Val)	//функция возвращает номер страницы (от 0 до 7) в зависимости от параметра Val (от 0 до 63)
{
	if(Val > 63) return 0;
	return (uint8_t)(Val/8);
}

#endif	//__LCDGRAPHIC_C
