#include "stm32f10x.h"
#include "SSD2119.h"
#include "SSD2119_api.h"


/****************************************************************************
* 名    称：Lcd_CmpColor()
* 功    能：判断颜色值是否一致。
* 入口参数：color1		颜色值1
*		        color2		颜色值2
* 出口参数：返回1表示相同，返回0表示不相同。
* 说    明：
****************************************************************************/
#define  Lcd_CmpColor(color1, color2)	( (color1&0x01) == (color2&0x01) )


/****************************************************************************
* 名    称：u16 Lcd_Color565(u32 RGB)
* 功    能：将RGB颜色转换为16位颜色。
* 入口参数：RGB  颜色值
* 出口参数：返回16位RGB颜色值。
* 说    明：
* 调用方法：i=Lcd_Color565(0xafafaf);
****************************************************************************/
u16 Lcd_Color565(u32 RGB)
{
  u8  r, g, b;

  b = ( RGB >> (0+3) ) & 0x1f;		// 取B色的高5位
  g = ( RGB >> (8+2) ) & 0x3f;		// 取G色的高6位
  r = ( RGB >> (16+3)) & 0x1f;		// 取R色的高5位
   
  return( (r<<11) + (g<<5) + (b<<0) );		
}

/****************************************************************************
* 名    称：void Lcd_Text(u16 x, u16 y, u8 *str, u16 len,u16 Color, u16 bkColor)
* 功    能：在指定座标显示字符串
* 入口参数：x      行座标
*           y      列座标
*           *str   字符串
*           len    字符串长度
*           Color  字符颜色
*           bkColor字符背景颜色
* 出口参数：无
* 说    明：
* 调用方法：Lcd_Text(0,0,"0123456789",10,0x0000,0xffff);
****************************************************************************/
void Lcd_Text(u16 x, u16 y, u8 *str, u16 len,u16 Color, u16 bkColor)
{
  u8 i;
  
  for (i=0;i<len;i++)
  {
    Lcd_PutChar((x+8*i),y,*str++,Color,bkColor);
  }
}

/****************************************************************************
* 名    称：void Lcd_Line(u16 x0, u16 y0, u16 x1, u16 y1,u16 color)
* 功    能：在指定座标画直线
* 入口参数：x0     A点行座标
*           y0     A点列座标
*           x1     B点行座标
*           y1     B点列座标
*           color  线颜色
* 出口参数：无
* 说    明：
* 调用方法：Lcd_Line(0,0,240,320,0x0000);
****************************************************************************/
void Lcd_Line(u16 x0, u16 y0, u16 x1, u16 y1,u16 color)
{
 	u16 x,y;
 	u16 dx;// = abs(x1 - x0);
 	u16 dy;// = abs(y1 - y0);

	if(y0==y1)
	{
		if(x0<=x1)
		{
			x=x0;
		}
		else
		{
			x=x1;
			x1=x0;
		}
  		while(x <= x1)
  		{
   			Lcd_SetPoint(x,y0,color);
   			x++;
  		}
  		return;
	}
	else if(y0>y1)
	{
		dy=y0-y1;
	}
	else
	{
		dy=y1-y0;
	}
 
 	if(x0==x1)
	{
		if(y0<=y1)
		{
			y=y0;
		}
		else
		{
			y=y1;
			y1=y0;
		}
  		while(y <= y1)
  		{
   			Lcd_SetPoint(x0,y,color);
   			y++;
  		}
  		return;
	}
	else if(x0 > x1)
 	{
		dx=x0-x1;
  		x = x1;
  		x1 = x0;
  		y = y1;
  		y1 = y0;
 	}
 	else
 	{
		dx=x1-x0;
  		x = x0;
  		y = y0;
 	}

 	if(dx == dy)
 	{
  		while(x <= x1)
  		{

   			x++;
			if(y>y1)
			{
				y--;
			}
			else
			{
   				y++;
			}
   			Lcd_SetPoint(x,y,color);
  		}
 	}
 	else
 	{
 		Lcd_SetPoint(x, y, color);
  		if(y < y1)
  		{
   			if(dx > dy)
   			{
    			s16 p = dy * 2 - dx;
    			s16 twoDy = 2 * dy;
    			s16 twoDyMinusDx = 2 * (dy - dx);
    			while(x < x1)
    			{
     				x++;
     				if(p < 0)
     				{
      					p += twoDy;
     				}
     				else
     				{
      					y++;
      					p += twoDyMinusDx;
     				}
     				Lcd_SetPoint(x, y,color);
    			}
   			}
   			else
   			{
    			s16 p = dx * 2 - dy;
    			s16 twoDx = 2 * dx;
    			s16 twoDxMinusDy = 2 * (dx - dy);
    			while(y < y1)
    			{
     				y++;
     				if(p < 0)
     				{
      					p += twoDx;
     				}
     				else
     				{
      					x++;
      					p+= twoDxMinusDy;
     				}
     				Lcd_SetPoint(x, y, color);
    			}
   			}
  		}
  		else
  		{
   			if(dx > dy)
   			{
    			s16 p = dy * 2 - dx;
    			s16 twoDy = 2 * dy;
	    		s16 twoDyMinusDx = 2 * (dy - dx);
    			while(x < x1)
    			{
     				x++;
     				if(p < 0)
	     			{
    	  				p += twoDy;
     				}
     				else
     				{
      					y--;
	      				p += twoDyMinusDx;
    	 			}
     				Lcd_SetPoint(x, y,color);
    			}
   			}
	   		else
   			{
    			s16 p = dx * 2 - dy;
    			s16 twoDx = 2 * dx;
	    		s16 twoDxMinusDy = 2 * (dx - dy);
    			while(y1 < y)
    			{
     				y--;
     				if(p < 0)
	     			{
    	  				p += twoDx;
     				}
     				else
     				{
      					x++;
	      				p+= twoDxMinusDy;
    	 			}
     				Lcd_SetPoint(x, y,color);
    			}
   			}
  		}
 	}
}

/****************************************************************************
* 名    称：void Lcd_Circle(u16 cx,u16 cy,u16 r,u16 color,u8 fill)
* 功    能：在指定座标画圆，可填充
* 入口参数：
* 出口参数：
* 说    明：
* 调用方法：
****************************************************************************/
void Lcd_Circle(u16 cx,u16 cy,u16 r,u16 color,u8 fill)
{
	u16 x,y;
	s16 delta,tmp;
	x=0;
	y=r;
	delta=3-(r<<1);

	while(y>x)
	{
		if(fill)
		{
			Lcd_Line(cx+x,cy+y,cx-x,cy+y,color);
			Lcd_Line(cx+x,cy-y,cx-x,cy-y,color);
			Lcd_Line(cx+y,cy+x,cx-y,cy+x,color);
			Lcd_Line(cx+y,cy-x,cx-y,cy-x,color);
		}
		else
		{
			Lcd_SetPoint(cx+x,cy+y,color);
			Lcd_SetPoint(cx-x,cy+y,color);
			Lcd_SetPoint(cx+x,cy-y,color);
			Lcd_SetPoint(cx-x,cy-y,color);
			Lcd_SetPoint(cx+y,cy+x,color);
			Lcd_SetPoint(cx-y,cy+x,color);
			Lcd_SetPoint(cx+y,cy-x,color);
			Lcd_SetPoint(cx-y,cy-x,color);
		}
		x++;
		if(delta>=0)
		{
			y--;
			tmp=(x<<2);
			tmp-=(y<<2);
			delta+=(tmp+10);
		}
		else
		{
			delta+=((x<<2)+6);
		}
	}
}

/****************************************************************************
* 名    称：void Lcd_Rectangle(u16 x0, u16 y0, u16 x1, u16 y1,u16 color,u8 fill)
* 功    能：在指定区域画矩形，可填充颜色
* 入口参数：
* 出口参数：
* 说    明：
* 调用方法：
****************************************************************************/
void Lcd_Rectangle(u16 x0, u16 y0, u16 x1, u16 y1,u16 color,u8 fill)
{
	if(fill)
	{
		u16 i;
		if(x0>x1)
		{
			i=x1;
			x1=x0;
		}
		else
		{
			i=x0;
		}
		for(;i<=x1;i++)
		{
			Lcd_Line(i,y0,i,y1,color);
		}
		return;
	}
	Lcd_Line(x0,y0,x0,y1,color);
	Lcd_Line(x0,y1,x1,y1,color);
	Lcd_Line(x1,y1,x1,y0,color);
	Lcd_Line(x1,y0,x0,y0,color);
}

/****************************************************************************
* 名    称：void  Lcd_Square(u16 x0, u16 y0, u16 with, u16 color,u8 fill)
* 功    能：在指定区域画正方形，可填充颜色
* 入口参数：
* 出口参数：
* 说    明：
* 调用方法：
****************************************************************************/
void  Lcd_Square(u16 x0, u16 y0, u16 width, u16 color,u8 fill)
{
	Lcd_Rectangle(x0, y0, x0+width, y0+width, color,fill);
}

void Lcd_ClearCharBox(u16 x,u16 y,u16 color)
{
	Lcd_Rectangle(x*8,y*16,x*8+8,y*16+16,color,TRUE); 
}

void Lcd_FastRectangle(u16 x0, u16 y0, u16 x1, u16 y1,u16 color,u8 fill)
{
  u32  i;
  u32  difference;
  Lcd_Line(x0,y0,x0,y1,color);
  Lcd_Line(x0,y1,x1,y1,color);
  Lcd_Line(x1,y1,x1,y0,color);
  Lcd_Line(x1,y0,x0,y0,color);
  difference = x1-x0;
if(fill) {
while (y0<=y1) {
  Lcd_SetCursor(x0, y0);
  Lcd_WR_Start();
  for(i=0;i<=difference;i++) {  //Write all pixels to ram, and then update display (fast)
    Lcd_WriteData(color);
    Clr_nWr
    Set_nWr;
  } 
  y0++;
  Lcd_WR_End();
}
}
}

void  Lcd_FastSquare(u16 x0, u16 y0, u16 width, u16 color,u8 fill)
{
	Lcd_FastRectangle(x0, y0, x0+width, y0+width, color,fill);
}

void Lcd_FastClearCharBox(u16 x,u16 y,u16 color)
{
	Lcd_FastRectangle(x*8,y*16,x*8+8,y*16+16,color,TRUE); 
}

void DispPic320_240(const unsigned char *str)
{

	u32 temp;
	ColorTypeDef color;
	Lcd_SetCursor(0x00, 0x0000);
	//Lcd_WriteReg(0x0050,0x00);//水平 GRAM起始位置
	//Lcd_WriteReg(0x0051,239);//水平GRAM终止位置
	//Lcd_WriteReg(0x0052,0);//垂直GRAM起始位置
	//Lcd_WriteReg(0x0053,319);//垂直GRAM终止位置   
	Lcd_WR_Start();
	//Set_Rs;
  
	for (temp = 2; temp < 320*240 + 2; temp++)
	{  
		color.U8[1] =*(unsigned short *)(&str[ 2 * temp]);
		color.U8[0]=*(unsigned short *)(&str[ 2 * temp+1]);
		//DataToWrite(i);
	
		Lcd_WriteData(color.U16);
		Clr_nWr;
		Set_nWr;
	}
Lcd_WR_End();

//==============================  
}

void DispPic(u16 x0, u16 y0, const unsigned char *str)
{

	u32 temp;
    u32  i;
    u32 difference;
    
    u16 x1;
    u16 y1;
    u16 imageWidth;
    u16 imageHeight;
    
    ColorTypeDef color;
    
    color.U8[1] =*(unsigned short *)(&str[ 0]);
	color.U8[0]=*(unsigned short *)(&str[ 1]);
    imageWidth = color.U16;
    x1 = imageWidth + x0;

    color.U8[1] =*(unsigned short *)(&str[ 2]);
	color.U8[0]=*(unsigned short *)(&str[ 3]);
    imageHeight = color.U16;
    y1 = imageHeight + y0;

    temp = 2;
    difference = x1-x0;
    while (y0<=y1-1) {
      Lcd_SetCursor(x0, y0);
      Lcd_WR_Start();
      for(i=0;i<=imageWidth-1;i++) {  //Write all pixels to ram, and then update display (fast)
        color.U8[1] =*(unsigned short *)(&str[ 2 * temp]);
	    color.U8[0]=*(unsigned short *)(&str[ 2 * temp+1]);
        Lcd_WriteData(color.U16);
        Clr_nWr
        Set_nWr;
        
        temp++;
      } 
      y0++;
      Lcd_WR_End();
    }

//==============================  
}