#include "GUI_tjc_hmi.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>

#include "proto_modbus_lib.h"


#include "bsp_Flash.h"  // 添加Flash操作
#include "bsp_uart.h"

#include "app_leakage.h"

/*串口发送缓冲区*/
#define HMI_TX_BUFFER_NUM (2048) 
/*字符发送拼接 缓冲区*/
#define GUI_TJC_HMI_TEXT_BUFFER_NUM (256)

/*帧头*/
#define HMI_PROTO_FRAME_HEADER1             (0xAA)
#define HMI_PROTO_FRAME_HEADER2             (0x55)
/*操作*/
#define HMI_PROTO_CMD_GET                   (0x03) /*获取数据数据*/
#define HMI_PROTO_CMD_SET                   (0x10) /*设置信息*/
/*界面*/
#define HMI_PROTO_GUI_MAIN                  (0x10)/*主界面          */
#define HMI_PROTO_GUI_CURR_ALARM            (0x11)/*实时报警界面    */
#define HMI_PROTO_GUI_DETAIL_MAIN           (0x12)/*主界面_详细信息 */
#define HMI_PROTO_GUI_LOGIN                 (0x13)/*登录界面        */
#define HMI_PROTO_GUI_HISTORY_ALARM         (0x14)/*历史报警界面    */
#define HMI_PROTO_GUI_TCP_CONFIG            (0x15)/*网络配置界面    */
#define HMI_PROTO_GUI_DEVICE_CONFIG         (0x16)/*设备配置界面    */
#define HMI_PROTO_GUI_HELP                  (0x17)/*帮助界面        */

#define HMI_PROTO_ASCII_RX_DELINITER           (0xAA)/*接收分隔符*/

#define HMI_PROTO_ASCII_TX_DELINITER           (0xFF)/*发送分隔符*/
#define HMI_PROTO_ASCII_TX_DELINITER_NUM        (3)/*发送分隔符数量*/


static void gui_tjc_hmi_init(void);
static void gui_tjc_hmi_communication_data_analysis(u8 *p_data, u16 len, void *rx_uart);

/*串口发送缓冲区*/
static u8 hmi_tx_buffer[HMI_TX_BUFFER_NUM];
/*字符发送拼接 缓冲区*/
static char gui_tjc_hmi_text_buffer[GUI_TJC_HMI_TEXT_BUFFER_NUM];
/*字符名称 端口号*/
static char *hmi_proto_string_com[] = 
{
    "COM1",
    "COM2",
    "COM3",
    "COM4"
};

/*字符名称 波特率*/
static char *hmi_proto_string_baudrate[] = 
{
    "4800",
    "9600",
    "19200",
    "57600",
    "115200",
};


static bsp_uart_t * p_rx_uart = NULL;

gui_tjc_hmi_t tjc_hmi = 
{
   .init =  gui_tjc_hmi_init,
};

gui_tjc_hmi_t *p_tjc_hmi = &tjc_hmi;



/*屏幕协议初始化*/
static void gui_tjc_hmi_init(void)
{
    com_uart1.rx_data_analysis = gui_tjc_hmi_communication_data_analysis;
}


/*发送接口*/
static void gui_tjc_hmi_data_send(u8 *p_data,u16 len)
{
    if(p_rx_uart != NULL)
    {
        p_rx_uart->send(p_rx_uart,p_data,len);
    }
}


/*设置对应的控件
x：第几行
y：第几个
buffer：写入的buffer
format：格式化输入
...：不定长
*/
static u16 gui_tjc_hmi_tx_text_display(u16 x,u16 y,char *buffer,const char *format,...)
{
    u16 i,len;
    s16 state;
    va_list arg;
    
    /*清空缓冲区*/
    memset(gui_tjc_hmi_text_buffer,0,sizeof(gui_tjc_hmi_text_buffer));
    
    va_start(arg,format);
    /*格式化转成字符串*/
	state = vsnprintf(gui_tjc_hmi_text_buffer,GUI_TJC_HMI_TEXT_BUFFER_NUM,format,arg);
	if(-1 == state || state > GUI_TJC_HMI_TEXT_BUFFER_NUM)
	{
		va_end(arg);
		printf("Length REEOR");
		return 0;
	}   
    
    /*拼接字符串*/
    sprintf(buffer,"t%d_%d.txt=\"%s\"",x,y,gui_tjc_hmi_text_buffer);
    len = strlen(buffer);
    for(i=0;i<HMI_PROTO_ASCII_TX_DELINITER_NUM;i++)
    {
        buffer[len + i] = HMI_PROTO_ASCII_TX_DELINITER;
    }
    va_end(arg);
    return len + 3;   
}


/*主界面响应*/
static void gui_tjc_hmi_main_send(u8 cmd,u8 opa,u8 *p_data)
{
    /*每页显示的区域数量*/
    #define MAIN_PAGE_SUB_DEVICE_NUM (4)
    
    u16 len = 0,i,j,x,y,index;
    u8 page_num,remain_region_num;

    memset(hmi_tx_buffer,0,sizeof(hmi_tx_buffer));
    
    /*计算页面数量*/
    page_num = leakage.region_num / MAIN_PAGE_SUB_DEVICE_NUM;
    remain_region_num = leakage.region_num % MAIN_PAGE_SUB_DEVICE_NUM;/*剩余区域数量*/
    if(remain_region_num > 0)
    {
        page_num++;
    }
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:/*读取区域信息*/
            {
                if(p_tjc_hmi->page.main_index == page_num - 1 && remain_region_num >0)/*显示剩余区域*/
                {
                    for(j=0;j<remain_region_num;j++)
                    {
                        index = p_tjc_hmi->page.main_index * MAIN_PAGE_SUB_DEVICE_NUM + j;
                        x = j;
                        /*名称*/
                        y = 0;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.region_data[index].name);
                        /*区域内设备总数量*/
                        y = 1;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].sub_device_num);
                        /*漏液数量*/
                        y = 2;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].leakage_num);
                        /*断带*/
                        y = 3;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].open_num);
                        /*通讯*/
                        y = 4;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].time_out_num);   
                    }
                }
                else
                {
                    for(j=0;j<MAIN_PAGE_SUB_DEVICE_NUM;j++)
                    {
                        index = p_tjc_hmi->page.main_index*MAIN_PAGE_SUB_DEVICE_NUM + j;
                        x = j;
                        /*名称*/
                        y = 0;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.region_data[index].name);
                        /*区域内设备总数量*/
                        y = 1;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].sub_device_num);
                        /*漏液数量*/
                        y = 2;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].leakage_num);
                        /*断带*/
                        y = 3;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].open_num);
                        /*通讯*/
                        y = 4;   
                        len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].time_out_num);   
                    }
                }
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x03:/*翻页*/
            {
                if(0x01 == p_data[0])
                {
                    if(page_num - 1 <= p_tjc_hmi->page.main_index)
                    {
                        p_tjc_hmi->page.main_index = 0;
                    }
                    else
                    {
                        p_tjc_hmi->page.main_index++;
                    }
                }
                else
                {
                    
                    if(0 == p_tjc_hmi->page.main_index)
                    {
                        p_tjc_hmi->page.main_index = page_num - 1;
                    }
                    else
                    {
                        p_tjc_hmi->page.main_index--;
                    }
                }
            }
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}

/*实时报警响应*/
static void gui_tjc_hmi_curr_alarm_send(u8 cmd,u8 opa,u8 *p_data)
{
    u16 len = 0,i;
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}
/*主界面详情*/
static void gui_tjc_hmi_detail_main_send(u8 cmd,u8 opa,u8 *p_data)
{
    u16 len = 0,i;
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}
/*登录界面*/
static void gui_tjc_hmi_login_send(u8 cmd,u8 opa,u8 *p_data)
{
    u16 len = 0,i;
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}

/*历史报警界面*/
static void gui_tjc_hmi_history_alarm_send(u8 cmd,u8 opa,u8 *p_data)
{
    u16 len = 0,i;
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}

/*网络配置界面*/
static void gui_tjc_hmi_tcp_config_send(u8 cmd,u8 opa,u8 *p_data)
{
    u16 len = 0,i;
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}

/*设备配置界面    */
static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
{
    u16 len = 0,i;
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}
/*帮助界面*/
static void gui_tjc_hmi_help_send(u8 cmd,u8 opa,u8 *p_data)
{
    u16 len = 0,i;
    
    if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
    else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
    {
        switch(opa)
        {
            case 0x01:
            {
            
            }break;
            case 0x02:
            {
            
            }break;
            default:return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer,len);
    }
}
/*屏幕指令解析*/
static void gui_tjc_hmi_communication_data_analysis(u8 *p_data, u16 len, void *rx_uart)
{
    u8 cmd,data,gui_id,opa,*p_offset_data;
    u16 i,modbus_crc16,check_crc16;
    /*长度不足*/
    if(len < 5)
    {
        return ;
    }
    /*检测帧头*/
    if(p_data[0] != HMI_PROTO_FRAME_HEADER1 || p_data[1] != HMI_PROTO_FRAME_HEADER2)
    {
        return ;
    }
    /*校验位*/
    check_crc16 = p_data[len-2] << 8 | p_data[len-1];
    modbus_crc16 = modbus_lib_crc16(p_data,len-2);
    modbus_crc16 = (modbus_crc16 >> 8) | (modbus_crc16 << 8);
    if(modbus_crc16 != check_crc16) 
    {
        return ;
    }
    
    /*CMD*/
    cmd = p_data[2];
    if(cmd != HMI_PROTO_CMD_GET || HMI_PROTO_CMD_GET !=  HMI_PROTO_CMD_SET)
    {
        return ;
    }
    gui_id = p_data[3];                 /*gui_id*/
    opa    = p_data[4];                 /*操作码*/
    p_offset_data = &p_data[5];         /*附带数据*/
    p_rx_uart =  (bsp_uart_t *)rx_uart; /*串口指针*/                         
    switch(gui_id)
    {
        case HMI_PROTO_GUI_MAIN           :
        {
            gui_tjc_hmi_main_send(cmd,opa,p_offset_data);
        }break;
        case HMI_PROTO_GUI_CURR_ALARM     :
        {
            gui_tjc_hmi_curr_alarm_send(cmd,opa,p_offset_data);
        }break;
        case HMI_PROTO_GUI_DETAIL_MAIN    :
        {
            gui_tjc_hmi_detail_main_send(cmd,opa,p_offset_data);
        }break;
        case HMI_PROTO_GUI_LOGIN          :
        {
            gui_tjc_hmi_main_send(cmd,opa,p_offset_data);
        }break;
        case HMI_PROTO_GUI_HISTORY_ALARM  :
        {
            gui_tjc_hmi_history_alarm_send(cmd,opa,p_offset_data);
        }break;
        case HMI_PROTO_GUI_TCP_CONFIG     :
        {
            gui_tjc_hmi_tcp_config_send(cmd,opa,p_offset_data);
        }break;
        case HMI_PROTO_GUI_DEVICE_CONFIG  :
        {
            gui_tjc_hmi_device_config_send(cmd,opa,p_offset_data);
        }break;
        case HMI_PROTO_GUI_HELP           :
        {
            gui_tjc_hmi_help_send(cmd,opa,p_offset_data);
        }break;
    }  
}
