/*
 * windows.c
 *
 *  Created on: Aug 6, 2021
 *      Author: wuwenfeng
 */

#include "windows.h"
#include "touch.h"
extern touch_device t0;
//接口
//设置屏幕像素坐标
void Inteface_SetCursor(uint16_t Xpos, uint16_t Ypos)
{
	LCD_SetCursor(Xpos,Ypos);      				//设置光标位置
	LCD_REG_ADDRESS=lcddev.wramcmd;     		//开始写入GRAM
}
//往像素坐标写入一个颜色
void Inteface_SetColor(uint16_t color)
{
	LCD_DATA_ADDRESS=color;
}
//新建一个UI对象
//当时都想法是类似windows的多桌面，每个桌面都能有n个窗口
UI *UI_Init(COLOR_16 background)
{
	UI *ui;
	ui = (UI*)malloc(sizeof(UI));
	if(ui!=NULL)
	{
		ui->x=0;
		ui->y=0;
		ui->high=240;
		ui->width=320;
		ui->background=background;
		ui->windows=NULL;
		ui->last_windows=NULL;
		ui->refresh_ui_flag=1;
		ui->moveed_windwos=NULL;
		ui->First_click_flag==0;
		/*
		ui->touch=(touch_device*)malloc(sizeof(touch_device));
		if(ui->touch!=NULL)
		{
			ui->touch->louck=0;
			ui->touch->tick=0;
			ui->touch->time=0;
			ui->touch->times=0;
			ui->touch->x=0;
			ui->touch->y=0;
			ui->touch->old_x=0;
			ui->touch->old_y=0;
			ui->touch->acc_x=0;
			ui->touch->acc_y=0;

		}
*/

		return ui;
	}
	return NULL;

}
//新建一个窗口
//返回窗口的指针
//将窗口挂载到某个ui
window *New_Window(UI *ui,uint16_t x,uint16_t y,uint16_t width,uint16_t high,COLOR_16 background,const char *title)
{
	window *temp_window;
	temp_window = (window*)malloc(sizeof(window));
	if(temp_window!=NULL)
	{
		temp_window->background=background;
		temp_window->high=high;
		temp_window->width=width;
		temp_window->x=x;
		temp_window->y=y;
		temp_window->refresh_windows_flag=2;
		temp_window->touch_flag=0;
		for(int a=0;a<16;a++)
		{
			temp_window->title[a]=title[a];
		}
	}else{return NULL;}

	windows_stack *temp_windows_stack;
	temp_windows_stack=ui->last_windows;
	if(temp_windows_stack==NULL)
	{
		temp_windows_stack=(windows_stack*)malloc(sizeof(windows_stack));
		temp_windows_stack->up=NULL;
		ui->windows=temp_windows_stack;
	}else
	{
/*
		while(temp_windows_stack->next!=NULL)
		{
			temp_windows_stack=temp_windows_stack->next;
		}
*/
		windows_stack *up=temp_windows_stack;//备份当前对象指针
		temp_windows_stack->next=(windows_stack*)malloc(sizeof(windows_stack));
		temp_windows_stack=temp_windows_stack->next;
		temp_windows_stack->up=up;
	}
	temp_windows_stack->next=NULL;
	temp_windows_stack->window=temp_window;

	ui->last_windows=temp_windows_stack;

	return temp_window;

}
//关闭某个窗口
//挺麻烦的，除了要释放窗口内存，还要去ui抹掉窗口的指针
void Close_Windows_Stack(UI *ui,windows_stack *temp_windows_stack)
{

	if(temp_windows_stack==ui->windows)
	{
		if(temp_windows_stack->next!=NULL)
		{
			ui->windows=temp_windows_stack->next;
			ui->windows->up=NULL;
		}else
		{
			ui->windows=NULL;
			ui->last_windows=NULL;
		}

	}else if(temp_windows_stack==ui->last_windows)
	{
		if(temp_windows_stack->up!=NULL)
		{
			ui->last_windows=temp_windows_stack->up;
			ui->last_windows->next=NULL;
		}else
		{
			ui->windows=NULL;
			ui->last_windows=NULL;
		}
	}else
	{
		temp_windows_stack->up->next=temp_windows_stack->next;  //取出这个节点 把节点的上下补上链接
		temp_windows_stack->next->up=temp_windows_stack->up;
	}

	free(temp_windows_stack->window);
	free(temp_windows_stack);



}

//设置窗口标题
void Set_Windows_Title(window *this_window,const char *title)
{
	for(int a=0;a<16;a++)
	{
		this_window->title[a]=title[a];
	}
}
//测试用
void Set_Windows_XY_BY_ACC(window *temp_window,int acc_x,int acc_y)
{
	temp_window->x=temp_window->x+acc_x;
	temp_window->y=temp_window->y+acc_y;
}

//显示一个窗口
void Refresh_Window(UI *ui,window *temp_window)
{
	//开始绘制窗口//填充窗口背景
	int x,y;
	char z;
	for(uint16_t temp_y=0;temp_y<temp_window->high;temp_y++)
	{
		z=1;
		for(uint16_t temp_i=0;temp_i<temp_window->width;temp_i++)
		{
			x=temp_window->x+temp_i;
			y=temp_window->y+temp_y;
			if(y>=ui->y&&z==1)
			{
				Inteface_SetCursor(x,y);
				z=0;
			}
			if(x>=ui->x)
			{
				if(temp_y<16)
				{
					if(temp_i>temp_window->width-16)
					{
						Inteface_SetColor(RED);
					}else
					{
						Inteface_SetColor(BLUE);
					}
				}else
				{
					if(temp_i==0||temp_y==0||temp_i==temp_window->width-1||temp_y==temp_window->high-1)
					{
						Inteface_SetColor(BLUE);
					}else
					{
						Inteface_SetColor(temp_window->background);
					}
				}

			}



		}
	}
	//绘制bar
	/*
	for(uint16_t temp_y=0;temp_y<16;temp_y++)
	{
		Inteface_SetCursor(temp_window->x,temp_window->y+temp_y);
		for(uint16_t temp_i=0;temp_i<temp_window->width;temp_i++)
		{
			if(temp_i>temp_window->width-16)
			{
				Inteface_SetColor(RED);
			}else
			{
				Inteface_SetColor(BLUE);
			}

		}
	}
	*/
	//显示title
	LCD_ShowString(temp_window->x,temp_window->y,&temp_window->title,16,WHITE,WHITE);

}
/*
 * 很可惜 辛辛苦苦写的代码要被放弃
 * 用算法实现遮挡关系计算真挺蠢
 *
 * */
void Refresh_UI(UI *ui)
{
	int flag=0;
	uint16_t dot_y=0,dot_x=0;
	//画背景
	for(dot_y=ui->y;dot_y<ui->high;dot_y++)
	{
		Inteface_SetCursor(dot_x,dot_y);
		for(dot_x=ui->x;dot_x<ui->width;dot_x++)
		{
			Inteface_SetColor(ui->background);
		}

	}
	windows_stack *temp_windows_stack,*temp_windows_stack2;
	temp_windows_stack=ui->windows;
	do
	{
		if(temp_windows_stack!=NULL)
		{
			flag=1;
			Refresh_Window(ui,temp_windows_stack->window);
			//绘制下一个窗口
			temp_windows_stack=temp_windows_stack->next;
		}else
		{
			flag=0;
		}

	}while(flag);

	//画背景
	/*
	for(dot_y=0;dot_y<240;dot_y++)
	{
		Inteface_SetCursor(dot_x,dot_y);
		for(dot_x=0;dot_x<320;dot_x++)
		{
			flag2=1;
			temp_windows_stack2 =ui->windows;
			for(uint16_t temp_a=0;temp_a<windows_num;temp_a++)
			{
				if(Chack(temp_windows_stack2->window,dot_x,dot_y))
				{
					flag2=0;
					flag3=1;
					break;
				}
				temp_windows_stack2=temp_windows_stack2->next;
			}
			if(flag2==1)
			{
				if(flag3==1)
				{
					Inteface_SetCursor(dot_x,dot_y);
					flag3=0;
				}
				Inteface_SetColor(ui->background);
			}
		}

	}
*/

}


/*
 * 检查坐标是否命中窗口
 *
 * */

#define BODY  1
#define BAR   2
#define CLOSE 3

uint8_t Chack(window *this_window,int x,int y)
{
	int a=0;

	if(((x>=this_window->x)&&(x<(this_window->x+this_window->width)))&&((y>=this_window->y+16)&&(y<(this_window->y+this_window->high))))
	{
		a=1;
	}
	if(((x>=this_window->x)&&(x<(this_window->x+this_window->width-16)))&&((y>=this_window->y)&&(y<(this_window->y+16))))
	{
		a=2;
	}
	if((x>=(this_window->x+this_window->width-16))&&(x<(this_window->x+this_window->width))&&((y>=this_window->y)&&(y<(this_window->y+16))))
	{
		a=3;
	}
	return a;

}

void UI_Server(UI *ui)
{

	windows_stack *temp_windows_stack=NULL;
	window *temp_window;
	//touch_device *temp_touch=NULL;
	int flag=0;
	uint8_t hit_flag=0;

	int t_x,t_y;
	//touch
	//temp_touch=ui->touch;
	if(t0.c)//TP_XY(&t_x, &t_y))
	{
		if(t0.d)
		{
			t_x=t0.pix_x;
			t_y=t0.pix_y;
			temp_window=NULL;

			if(ui->moveed_windwos==NULL)
			{
				if(ui->First_click_flag==0)
				{
					ui->First_click_flag=1;
					temp_windows_stack=ui->last_windows;                           //获取ui中最前端的窗口  从前往后扫描
					do
					{
						if(temp_windows_stack!=NULL)                               //如果有窗口就开始扫描
						{
							flag=1;                                                //检查到有窗口 需要循环一次以检查是否有下一个窗口
							//
							temp_window=temp_windows_stack->window;                  //取出这个窗口
							hit_flag=Chack(temp_window,t_x,t_y); //检查触摸是否命中 直接返回命中窗口的位置
							if(hit_flag)     										 // 命中继续
							{

								temp_window->touch_flag=1;
								temp_window->touch_x=t_x;
								temp_window->touch_y=t_y;
								if(temp_windows_stack!=ui->last_windows)           //检查是否最前端的窗口 如果不是就放最前面
								{
									if(temp_windows_stack!=ui->windows)            //检查是否最后端的窗口  因为显示是从最后端往前显示的 所以ui有最后端窗口的入口
									{
										temp_windows_stack->up->next=temp_windows_stack->next;  //取出这个节点 把节点的上下补上链接
										temp_windows_stack->next->up=temp_windows_stack->up;
									}else
									{
										ui->windows=temp_windows_stack->next;       //如果是最后端的窗口 则取出这个节点后入口就变下一个节点了
										ui->windows->up=NULL;                       //倒数第二变最后端  在走就没了  所以要清空指针
									}
									temp_windows_stack->next=NULL;                  //取出的节点要放在最前端 所以 无法再往前 清空往前的指针
									temp_windows_stack->up=ui->last_windows;        //上一个指针就是原来的最后一个
									ui->last_windows->next=temp_windows_stack;      //原来的最后一个指向现在的最后一个
									ui->last_windows=temp_windows_stack;            //更新ui中的最后一个的入口
									ui->refresh_ui_flag=1;                          //发生了变化 刷新ui的显示
									temp_window->refresh_windows_flag=1;
								}

								//检查标中窗口的什么位置
								switch(hit_flag)
								{
								case CLOSE:
									Close_Windows_Stack(ui,temp_windows_stack);
									ui->refresh_ui_flag=1;                          //发生了变化 刷新ui的显示
									break;
								case BAR:
									ui->moveed_windwos=temp_window;
									ui->move_x=t_x-temp_window->x;
									ui->move_y=t_y-temp_window->y;

									break;
								case BODY:
									//ui->background=temp_windows_stack->window->background;
									//ui->refresh_ui_flag=1;
									break;
								}


								flag=0;                                             //结束扫描 防止穿透当前窗口
							}else
							{


							}
							temp_windows_stack=temp_windows_stack->up;              //往前扫描
						}else
						{
							flag=0;                                                 //一个窗口都没有 直接结束循环
						}
					}while(flag);
				}

			}else
			{
				temp_window=ui->moveed_windwos;
				temp_window->x=(t_x-ui->move_x);
				temp_window->y=(t_y-ui->move_y);

				if(temp_window->x<0){temp_window->x=0;}
				if(temp_window->y<0){temp_window->y=0;}

				if(temp_window->x+temp_window->width>320){temp_window->x=320-temp_window->width;}
				if(temp_window->y+temp_window->high>240){temp_window->y=240-temp_window->high;}

				temp_window->refresh_windows_flag=1;
				ui->refresh_ui_flag=1;
				//发生了变化 刷新ui的显示
			}
		}




	}else
	{
		if(ui->First_click_flag==1)
		{
			ui->First_click_flag=0;
		}
		if(ui->moveed_windwos!=NULL)
		{
			ui->moveed_windwos=NULL;
		}


	}
	//display
	if(ui->refresh_ui_flag==1)
	{
		ui->refresh_ui_flag=0;
		Refresh_UI(ui);

	}

}

