#include "PDFReader.h"  // 引入 PDFReader 头文件
#include <sstream>       // 处理字符串流
#include <regex>         // 使用正则表达式
#include <iterator>      // 迭代器支持
#include <vector>        // 使用动态数组
#include <GL/glut.h>     // OpenGL 用于渲染 PDF
#include <cstring>       // 处理 C 风格字符串

// 构造函数: 打开 PDF 文件
PDFReader::PDFReader(const std::string& filepath) {
    // 以二进制模式打开文件
    file.open(filepath, std::ios::binary);  

    // 检查文件是否成功打开
    if (!file) {  
        // 输出错误信息
        std::cerr << "无法打开 PDF 文件: " << filepath << std::endl;  
    }
}

// 析构函数: 关闭 PDF 文件
PDFReader::~PDFReader() {
    // 检查文件是否仍然打开
    if (file.is_open()) {  

        // 关闭文件
        file.close(); 
    }
}

// 解析 JPEG (DCTDecode) 图片
void PDFReader::extractImages() {
    // 如果文件未打开，直接返回
    if (!file.is_open()) return; 

    // 将文件指针移动到文件开头
    file.seekg(0, std::ios::beg); 

    // 存储读取的行数据
    std::string line;  

    // 逐行读取 PDF 文件内容
    while (std::getline(file, line)) { 
        // 检测 JPEG 图片标识符
        if (line.find("/DCTDecode") != std::string::npos) {  
             // 输出发现信息
            std::cout << "发现 JPEG (DCTDecode) 图片" << std::endl; 

            // 存储 JPEG 图片的二进制数据
            std::vector<unsigned char> imageData;  
            // 缓冲区用于存储文件数据
            char buffer[1024];  
            // 逐块读取文件
            while (file.read(buffer, sizeof(buffer))) {  
                // 将数据存入 imageData
                imageData.insert(imageData.end(), buffer, buffer + file.gcount());  
            }

            // 使用 libjpeg 解析 JPEG 图片
            struct jpeg_decompress_struct cinfo;  // JPEG 解压缩结构体

            // JPEG 错误管理
            struct jpeg_error_mgr jerr; 

             // 绑定错误管理器
            cinfo.err = jpeg_std_error(&jerr); 

            // 初始化 JPEG 解压缩对象
            jpeg_create_decompress(&cinfo); 

            // 设定解码数据来源
            jpeg_mem_src(&cinfo, imageData.data(), imageData.size());  
            // 读取 JPEG 头部信息
            jpeg_read_header(&cinfo, TRUE);  
            // 开始解压
            jpeg_start_decompress(&cinfo); 

            // 输出图片尺寸
            std::cout << "JPEG 图片尺寸: " << cinfo.output_width << "x" << cinfo.output_height << std::endl;  

            // 结束解压
            jpeg_finish_decompress(&cinfo);  
            // 释放资源
            jpeg_destroy_decompress(&cinfo);  
        }
    }
}

// 解析 FlateDecode (压缩流)
void PDFReader::parseFlateDecode() {
    // 如果文件未打开，直接返回
    if (!file.is_open()) return;  

    // 存储压缩数据
    std::vector<unsigned char> compressedData;  
    // 存储读取的行数据
    std::string line;  

    // 将文件指针移动到文件开头
    file.seekg(0, std::ios::beg);  
    // 逐行读取 PDF 文件内容
    while (std::getline(file, line)) { 
        // 检测 FlateDecode 标识符
        if (line.find("/FlateDecode") != std::string::npos) {  
            // 输出发现信息
            std::cout << "发现 FlateDecode (压缩流)" << std::endl; 

            // 缓冲区用于存储压缩数据
            char buffer[1024];  
            // 逐块读取文件
            while (file.read(buffer, sizeof(buffer))) { 
                // 存入 compressedData
                compressedData.insert(compressedData.end(), buffer, buffer + file.gcount()); 
            }

            // 使用 zlib 解压缩数据
            std::vector<unsigned char> uncompressedData(compressedData.size() * 4);  // 预分配缓冲区

            // 初始化 zlib 流结构体
            z_stream strm = { 0 };  
            // 设定输入数据
            strm.next_in = compressedData.data();  
            // 设定输入数据大小
            strm.avail_in = compressedData.size();  
            // 设定输出缓冲区
            strm.next_out = uncompressedData.data();  
            // 设定输出缓冲区大小
            strm.avail_out = uncompressedData.size();  

            // 初始化解压
            inflateInit(&strm);  
            // 执行解压
            inflate(&strm, Z_FINISH);  
            // 结束解压
            inflateEnd(&strm); 


            // 输出解压后大小
            std::cout << "解压后数据大小: " << strm.total_out << " 字节" << std::endl; 
        }
    }
}

// 解析 PDF 表格
void PDFReader::parseTables() {

    // 如果文件未打开，直接返回
    if (!file.is_open()) return;  

    // 存储读取的行数据
    std::string line;  
    // 逐行读取 PDF 文件内容
    while (std::getline(file, line)) {  
        // 检测表格标识符
        if (line.find("/Table") != std::string::npos) { 
            // 输出发现信息
            std::cout << "发现 PDF 表格" << std::endl; 

            // 存储表格数据
            std::vector<std::vector<std::string>> tableData; 
            // 读取表格内容
            while (std::getline(file, line) && line.find("endtable") == std::string::npos) {  
                // 存储当前行数据
                std::vector<std::string> row;  
                // 使用字符串流分割数据
                std::stringstream ss(line);  
                // 存储单元格数据
                std::string cell; 


                // 以空格分割单元格
                while (std::getline(ss, cell, ' ')) { 
                    // 存入行数据
                    row.push_back(cell); 
                }
                // 存入表格数据
                tableData.push_back(row);  
            }


            // 输出表格行数
            std::cout << "表格数据解析完成，共 " << tableData.size() << " 行" << std::endl;  
        }
    }
}

// OpenGL 渲染 PDF 页面
display() {
    // 清空缓冲区
    glClear(GL_COLOR_BUFFER_BIT); 
    // 设置颜色（红色）
    glColor3f(1.0, 0.0, 0.0); 

    // 开始绘制四边形
    glBegin(GL_QUADS);  
    // 左下角
    glVertex2f(-0.5f, -0.5f);  
    // 右下角
    glVertex2f(0.5f, -0.5f);  
    // 右上角
    glVertex2f(0.5f, 0.5f); 
    // 左上角
    glVertex2f(-0.5f, 0.5f); 

    glEnd();  // 结束绘制

    glFlush();  // 刷新显示
}

void PDFReader::renderPDF() {
    int argc = 1;
    char* argv[1] = { (char*)"PDFRenderer" };
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutInitWindowSize(500, 500);
    glutCreateWindow("PDF 页面渲染");
    glutDisplayFunc(display);
    glutMainLoop();
}
