#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <string.h>
#include <iconv.h>
#include <stdlib.h>
#include <sys/file.h>
#include "pos_print.h"

#define INVALID_HANDLE_VALUE	-1
int g_Handle=INVALID_HANDLE_VALUE;
int g_uBaudrate=0;

int lock_set(int fd,int type)
{
	struct flock old_lock,lock;
	lock.l_whence = SEEK_SET;
	lock.l_start = 0;
	lock.l_len = 0;
	lock.l_type = type;
	lock.l_pid = getpid();
		
	fcntl(fd,F_GETLK,&lock);

	if(lock.l_type != F_UNLCK)
	{
		
		if (lock.l_type == F_RDLCK)  
		{
			printf("Read lock already set by %d\n",lock.l_pid);
		}
		else if (lock.l_type == F_WRLCK) 
		{
			printf("Write lock already set by %d\n",lock.l_pid);
		}						
	}
	
	lock.l_type = type;
	
	if ((fcntl(fd,F_SETLKW,&lock)) < 0)
	{
		printf("Lock failed : type = %d\n",lock.l_type);
		return 1;
	}
	
	switch (lock.l_type)
	{
		case F_RDLCK:
		{
			printf("Read lock set by %d\n",getpid());
		}
		break;
		case F_WRLCK:
		{
			printf("write lock set by %d\n",getpid());
		}
		break;
		case F_UNLCK:
		{
			printf("Release lock by %d\n",getpid());
			return 1;
		}
		break;
		
		default:
		break;

	}
	return 0;
}
int open_port(const char* szPort)
{
    //if(g_Handle != INVALID_HANDLE_VALUE)
    //    close(g_Handle);
    g_Handle= open(szPort, O_RDWR | O_NOCTTY | O_APPEND/* | O_NDELAY*/);
    
    if (g_Handle == INVALID_HANDLE_VALUE)
         printf("open_port failed\n");
    else
         printf("port is open ok \n");
    //lock_set(g_Handle, F_WRLCK);
    return (g_Handle);
}

bool set_port(int Baudrate)
{
    struct termios options;
    int flag;

    tcgetattr(g_Handle, &options);

    fcntl(g_Handle, F_SETFL, 0);
   
    if(9600==Baudrate)
    	g_uBaudrate=B9600;
    else if(19200==Baudrate)
        g_uBaudrate=B19200;
    cfsetispeed(&options, g_uBaudrate);
    cfsetospeed(&options, g_uBaudrate);

    options.c_cflag |= (CLOCAL | CREAD);
    /* Set to 8N1 */
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    /* HANDSHAKE 也称为 CRTSCTS */
    options.c_cflag |= CRTSCTS;

    /* RAW */
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;

    /* For read data from printer */
    options.c_cc[VMIN] = 0;
    options.c_cc[VTIME] = 1;

    flag = tcsetattr(g_Handle, TCSANOW, &options);
    if (flag < 0)
    {
        printf("setting port error\n");
    }

    //test
    char strCutPaper[] = "\x10\x04\x01\x00";   //打印机状态指令，如果打印机正常，返回长度为1 否则为0
    write(g_Handle, &strCutPaper, 4);
    
    //sleep(1);
    char temp[4]={0};
    int recvLen=read(g_Handle,temp,3);
    temp[recvLen]='\0';
    for(int i=0;i<recvLen;i++)
    {
         printf("-----length:%d  recv[%d]:%d\n",recvLen,i,temp[i]);
    }
    if(0==recvLen){
	tcflush(g_Handle,TCIOFLUSH); //清空终端未完成的输入/输出请求及数据
    	close_port();
	return false;
    }
    return true; 
}

void close_port()
{
    if (g_Handle != INVALID_HANDLE_VALUE)
    {
	    sleep(2);
	   // lock_set(g_Handle, F_UNLCK);  /* 给文件解锁*/
	  //  int res = tcflush(g_Handle,TCIOFLUSH);
            printf("close begin\n");
	    close(g_Handle);
	    printf("close end\n");
            g_Handle=INVALID_HANDLE_VALUE;
	    g_uBaudrate=0;      
    }

}

void cut_paper()
{
	//char strCutPaper[] = "\x1D\x56\x42\x00";
	char strCutPaper[] = "\x0A\x0A\x0A\x0A\x0A\x0A\x1B\x69\x00";
        write(g_Handle, &strCutPaper, 9);
}

void print(const char *data,int type)
{
	printf("data:%s\n",data);
	char *str = (char *)malloc(1024);
	
	if(1==type){
		strcpy(str,"\x1B\x40");
                strcat(str,data);
	}
        else if(2==type){
		strcpy(str,"\x1B\x40");
        	strcat(str,"\x1B\x21\x08");
		strcat(str,data);
		//strcat(str,"\x1B\x21\x00");
        }
        else if(3==type){
		if(B9600==g_uBaudrate){
	                strcpy(str,"\x1B\x40\x1B\x21\x00\x1B\x33\x18\x1B\x52\x00\x1B\x63\x34\x05");
                        strcat(str," \x1C\x57\x01");
                        strcat(str,"\x1B\x21\x30");
                        strcat(str,data);	
		}
		else{
              		strcpy(str,"\x1B\x40");
                	strcat(str,"\x1D\x21\x11");
        	        //strcat(str,"\x1B\x21\x38");
	                strcat(str,data);
		}
        }
        else if(4==type){
                if(B9600==g_uBaudrate){
                        strcpy(str,"\x1B\x40\x1B\x21\x00\x1B\x33\x18\x1B\x52\x00\x1B\x63\x34\x05");
                        strcat(str," \x1C\x57\x01");
                        strcat(str,"\x1B\x21\x38");
                        strcat(str,data);

                }
                else{
                       	strcpy(str,"\x1B\x40");
                	strcat(str,"\x1C\x57\x11");
                	strcat(str,"\x1B\x21\x38");
               		strcat(str,data);
                }
        }
        else if(5==type){
                if(B9600==g_uBaudrate){
                        strcpy(str,"\x1B\x40\x1B\x21\x00\x1B\x33\x18\x1B\x52\x00\x1B\x63\x34\x05");
                        strcat(str," \x1C\x57\x01");
                        strcat(str,"\x1B\x21\x10");
                        strcat(str,data);
                }
                else{
                        strcpy(str,"\x1B\x40");
                        strcat(str,"\x1D\x21\x01");
                        strcat(str,data);
                }
        }
        else if(6==type){
                if(B9600==g_uBaudrate){
                        strcpy(str,"\x1B\x40\x1B\x21\x00\x1B\x33\x18\x1B\x52\x00\x1B\x63\x34\x05");
                        strcat(str," \x1C\x57\x01");
                        strcat(str,"\x1B\x21\x18");
                        strcat(str,data);

                }
                else{
                        strcpy(str,"\x1B\x40");
                        strcat(str,"\x1D\x21\x01");
                        strcat(str,"\x1B\x21\x38");
                        strcat(str,data);
                }
        }
        else if(7==type){
                if(B9600==g_uBaudrate){
                        strcpy(str,"\x1B\x40");
                        strcat(str," \x1C\x57\x01");
                        strcat(str,"\x1B\x21\x38");
                        strcat(str,data);
                }
                else{
               		strcpy(str,"\x1B\x40");
        	        strcat(str,"\x1D\x21\x22");
	                strcat(str,data);
                }
        }
        else if(8==type){
                if(B9600==g_uBaudrate){
                        strcpy(str,"\x1B\x40");
			strcat(str,"\x1C\x57\x01");
                        strcat(str,"\x1B\x21\x38");
                        strcat(str,"\x1B\x72\x01");
                        strcat(str,data);

                }
                else{
                        strcpy(str,"\x1B\x40");
                	strcat(str,"\x1D\x21\x22");
                	strcat(str,"\x1B\x72\x01");
                	strcat(str,data);

                }
		//strcat(str,"\x1B\x72\x00");
               // strcat(str,"\x1B\x21\x00");
        }
	
	//char str[300];
	//strcpy(str,data);
	//strcat(str," thanks");
	strcat(str," \x0A\x0D");
	//printf("str is:%s\n",str);
	printf("str length:%d\n",strlen(str));
	int res = write(g_Handle, str, strlen(str));
	printf("write result:%d\n",res);
	free(str);
}


