#ifndef DATAFILEDSR_H
#define DATAFILEDSR_H

#include <QFileInfo>
#include <QFile>
#include <QString>
#include <QByteArray>
#include <QImage>
#include <QDebug>
#include <QPainter>
#include <QRgb>
#include "math.h"
#include <QBrush>
#include <QLinearGradient>

#include "dsrcryption.h"
#include "machine/comm/datadef.h"
#include "machine/comm/crc16.h"

//-----------------------------------------------
#define MAX_WIDTH_OF_DBZ    70     // 摆针最大范围7mm
#define MIN_WIDTH_OF_DBZ    2      // 摆针最小范围0.2mm

#define MAX_HEIGHT_OF_SBZ   40     // Y最大范围4mm
#define MIN_HEIGHT_OF_SBZ   8      // Y最小范围0.8mm

#define DSR_PREVIEW_SIDE    (15)     // 留边大小
#define DSR_PREVIEW_WIDTH   (156)   // 默认预览图区域宽度
#define DSR_PREVIEW_HEIGHT  (164)   // 默认预览图区域高度

#define DSR_VERSION_5       5.00f
#define DSR_VERSION_6_3   6.30f

typedef struct strDsrHead
{
// 0x00
    DWORD verCode;			// 文件版本 LSB
    DWORD cryWord;          // 加密字
    BYTE reserved1[8];		// 保留 8 字节
// 0x10
    DWORD dataBegin;		// 数据起始 LSB
    DWORD stepSize;         //  数据字段大小
    DWORD xyUnit;           //  长度数据单位
    DWORD rUnit;            //   角度数据单位
// 0x20
    DWORD stitches;			// 针数 LSB
    DWORD fileID;			// 文件id,和智能识别有关 = 0, 不能识别
    BYTE reserved3[8];		// 保留	8 字节
// 0x30
    s32 rangeNx;			// 范围 -X LSB
    s32 rangePx;			// 范围 +X LSB
    s32 rangeNy;			// 范围 -Y LSB
    s32 rangePy;			// 范围 +Y LSB
// 0x40
    long startX;			// 起点坐标X LSB
    long startY;			// 起点坐标Y LSB
    long anchorX;			// 定位点X LSB
    long anchorY;			// 定位点Y LSB
// 0x50
    DWORD angleFix;         // 角度修正量
// 0x54
    BYTE reserved4[0x84-0x54];		// 保留字节
// //0X84   //132
   u32 offsetEn;	// bit0,偏移点X向允许	0,不允许	1,允许
//                            // bit1,偏移点Y向允许	0,不允许	1,允许
//                            // bit2,平绣数据有无	0,无	1,有
//                            // bit3,激光数据有无	0,无	1,有
//                            // bit4,毛巾链式数据有无	0,无	1,有
//                            // bit5,缠绕锯齿盘带数据有无	0,无	1,有
// //0x82  //136
  s32 offsetX;     // 偏移点X
// //0x8C  //140
   s32 offsetY;
// //0x90   //144
  BYTE reserved5[0x118-0x90];		// 保留字节
// 0x118
    u8  begWorkHead;               // 以何种工作机头定点
// 0x119
    u8 reserved6[0x200-0x119]; //BYTE     // 保留字节
// 0x200
    u8 switchTable[0x400-0x200]; //BYTE     // 色序设定表, 支持512个色序设定

}__attribute__ ((packed)) DsrHead;

//dsr6.3版本的文件头扩展
typedef struct strDsrHead63
{
    //0x00
    u8 switchTable2[0x200-0x000]; //BYTE     // 换色表2（扩展色序设定表）,512个字节
    //0x200
    u8 towelHighTable[0x600-0x200]; //BYTE     // 毛巾高度设定表, 支持1024个高度设定，每个字节对应一个高度等级（0，非有效高度。1--11, 有效的高度等级）
}__attribute__ ((packed)) DsrHead63;

typedef struct strDsrStep
{
    BYTE ctrl;	// 控制字节
    BYTE attr;	// 属性字节
    WORD action;// 附加动作
    s32  dx;    // X绝对偏移
    s32  dy;	// Y绝对偏移
    s32  dr;	// R角度
}__attribute__ ((packed)) DsrStep;


//-----------------------------------------------

#define	DSR_NULL		0x00	// 文件结束
#define	DSR_SEWING		0x01	// 缝纫数据
#define	DSR_OFFSET		0x02	// 偏移数据
#define	DSR_CUTTING     0x03	// 切刀数据
#define	DSR_LASER		0x04	// 激光数据
#define	DSR_DRAWING     0x05	// 记号数据
#define	DSR_SEWING_R	0x06	// 第二缝纫数据

#define	DSR_PAUSE       0x08     // 暂停
#define	DSR_ANGLE       0x09     // 拐点
#define	DSR_CUT         0x0A     // 剪线
#define	DSR_JUMP        0x0B	 // 跳针
#define	DSR_PUNCH       0x0C	 // 冲孔
#define	DSR_EMB         0x0D	 // 绣花
#define	DSR_CHGND       0x0E	 // 换色
#define	DSR_CHENILLE   0x41	 // 毛巾环式
#define	DSR_CHAIN       0x42 // 毛巾链式
#define	DSR_TOWELHIGH       0x43 // 毛巾高度
#define DSR_COIL		       0x44	// 缠绕数据
#define DSR_SAWTOOTH	0x45	// 锯齿数据
#define DSR_RIBBON		   0x46	// 盘带数据

#define	DSR_END         0x10	 // 结束码

//-----------------------------------------------

#define DSR_EMB_DATADIRX    (1)     // X向数据坐标与下位机坐标系统的差异
#define DSR_EMB_DATADIRY    (1)     // Y向数据坐标与下位机坐标系统的差异
#define DSR_EMB_DATADIRR    (1)     // R向数据坐标与下位机坐标系统的差异

#define DSR_SHOWDIRX    (-1)     // X向显示坐标和数据坐标的差异
#define DSR_SHOWDIRY    (1)     // Y向显示坐标和数据坐标的差异

class DataFileDsr
{
public:
    DataFileDsr();
    ~DataFileDsr();

public:
    void initColor(int cnum = 0, QRgb * pColor = NULL);
    void initFile(const QString & fullPathName);

    int checkDsrVersion();//检查dsr文件版本，非5.2和6.3版本和错误格式返回-1
    void convertDataToEmbAbs();     // 转换为绝对数据
                                                 //是否保存         //笔宽             //是否渐变
    int createPreviewImage(QImage * pImg = NULL, int saveflag = 0, int penwidth = 1, int gradientFlag = 1, int reDraw = 0);  // 生成预览文件

public:
    void clear();
    void loadFile();
    void saveFile();
    void writePointToFile(u8 type, int x, int y, int st = 0,u8 workHead = 0);//写入起绣点到文件中
    void writeOffsetXYMoveToFile(s32 EnFlag,s32 offsetX,s32 offsetY);//偏移点XY写回dsr头文件
    inline const QString & getFileFullPathName() const {return m_fileFullPathName;}   // 文件路径名称
    inline QByteArray & getFileData() {return m_fileData;}         // 得到文件数据
    inline QByteArray & getEmbAbsData() {return m_embAbsData;}           // 得到转换后的数据
    QByteArray getTowelHighTable(QString path);  //获取毛巾高度
    QString getFileFullPath();      // 文件所在目录
    QString getFileFullName();      // 文件名称（包括扩展名）
    QString getFileName();          // 文件名称（不包括扩展名）
    QString getFileSuffix();        // 文件扩展名

    int getStitchNums();//得到数据的针数
    int getColorNums();//得到数据的色数
    int getTowelHighNums();//得到毛巾高度设置码数
    int getFileid();//得到fileid
    int getDatWidth();//得到数据的图形宽度
    int getDatHeight();//得到数据的图形高度
    int getMaxX();//得到数据最大X+
    int getMinX();//得到数据最小X-
    int getMaxY();//得到数据最大Y+
    int getMinY();//得到数据最小Y-
    int getJumpNeedleNum();//得到总的跳针数

protected:
    QString m_fileFullPathName; // 文件路径
    QByteArray m_embAbsData;    // 转换后的绝对坐标数据

public:
    QByteArray m_fileData;// 文件数据内容（原始数据）

private:
    int m_colorNum;//颜色数
    QRgb * m_pColor;//颜色rgb值
    QString m_fileName; // 文件路径

private:
    int m_minX;
    int m_maxX;
    int m_minY;
    int m_maxY;

private:
    int checkFileCryption();//检查dsr文件是否加密
    void getDsrMinMax();

private:
    int checkDefaultSwitchTable(int colornum = 0);
    QColor getBrightAdd(QColor embcolor);//补光增加
    QColor getBrightDec(QColor embcolor);//补光减少
};

#endif // DATAFILEDSR_H
