package com.example;

import static com.example.mtnlib.nmc_lib20.*;
import static com.example.mtnlib.nmc_lib20_err.*;
import static com.example.mtnlib.nmc_lib20_oem.*;
import static com.example.mtnlib.nmc_lib20_ext.*;
import static com.example.mtnlib.nmc_lib20_com.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import com.example.mtnlib.nmc_lib20_com.HAND;
import com.example.mtnlib.nmc_lib20_com.PHAND;
import com.example.mtnlib.nmc_lib20_ext.TCompXDimensParam;
import com.sun.jna.*;
import com.sun.jna.ptr.*;

/**
 * Java 示例：使用 JNA 调用 NMC 库进行数据采集
 * 仿照 C++ "位置比较例程（一维）" 测试用例
 */
public class Main {
    /**
     * 检查函数调用结果，处理错误
     */
    public static void checkError(short result, String operation) {
        if (result != RTN_CMD_SUCCESS) {
            System.err.printf("操作 %s 时发生错误 错误代码: %d%n", operation, result);
        }
    }
    
    public static void main(String[] args) {
        short rtn = 0;// 指令返回值
        short devNum = 0;// 设备序号，从0开始
        short axisNum = 0;// 轴号，从0开始

        // 句柄
        HAND devHandle = new HAND();// 设备句柄
        HAND axisHandle = new HAND();// 轴句柄
        HAND crdHandle = new HAND();// 坐标系句柄
        PHAND pDevHandle = new PHAND();//设备句柄指针
        PHAND pAxisHandle = new PHAND();//轴句柄指针
        PHAND pCrdHandle = new PHAND();// 坐标系句柄指针

        
        // 1. 打开设备
        rtn = NMC_DevOpen(devNum, pDevHandle);
        checkError(rtn, "NMC_DevOpen");
        devHandle = pDevHandle.getHandle();

        // 2. 打开轴
        rtn = NMC_MtOpen(devHandle, axisNum, pAxisHandle);
        checkError(rtn, "NMC_MtOpen");
        axisHandle = pAxisHandle.getHandle();

        // 3. 轴使能
        rtn = NMC_MtSetSvOn(axisHandle);
        checkError(rtn, "NMC_MtSetSvOn");

    /**
    * 正式测试部分
    */
        short compareAxisNum = 1; // 用于位置比较的轴号，从0开始，这里是第二轴
        short ch = 0; // 通道号
    
        // a. 配置参数
        TCompXDimensParam cmdXDPrm = new TCompXDimensParam(); // ✅ 必须 new
        cmdXDPrm.dimens = 1;            // 一维
        cmdXDPrm.axMask = 0x2;          // 轴为第二轴 (bit1)
        cmdXDPrm.src = 0;               // 位置源为规划位置
        cmdXDPrm.outCnts = 3;           // 三路输出
        // ✅ TCompXDimensParam 的数组字段必须在构造函数中初始化，否则为 null
        cmdXDPrm.outIndex[0] = 0;       // 输出通道1的序号为DO0
        cmdXDPrm.outIndex[1] = 1;       // 输出通道2的序号为DO1
        cmdXDPrm.outIndex[2] = 2;       // 输出通道3的序号为DO2
        cmdXDPrm.outType[0] = 0;        // 输出类型为脉冲方式
        cmdXDPrm.outType[1] = 0;
        cmdXDPrm.outType[2] = 0;
        cmdXDPrm.outChnType[0] = 0;     // 输出IO类型为通用输出 (GPO)
        cmdXDPrm.outChnType[1] = 0;
        cmdXDPrm.outChnType[2] = 0;
        cmdXDPrm.outStLevel[0] = 1;     // 初始电平为高
        cmdXDPrm.outStLevel[1] = 1;
        cmdXDPrm.outStLevel[2] = 1;
        cmdXDPrm.outGateTime[0] = 250;  // 脉冲宽度为250毫秒
        cmdXDPrm.outGateTime[1] = 350;  // 脉冲宽度为350毫秒
        cmdXDPrm.outGateTime[2] = 350;  // 脉冲宽度为350毫秒
        cmdXDPrm.errZone = 50;          // 容差半径为50个脉冲

        // 设置参数
        rtn = NMC_CompXDimensSetParam(devHandle, cmdXDPrm, ch); // ✅ 去掉 &
        checkError(rtn, "NMC_CompXDimensSetParam");

        // 设置输出模式：轮循输出模式
        rtn = NMC_CompXDimensSetCmpOutMode(devHandle, (short)1, ch);
        checkError(rtn, "NMC_CompXDimensSetCmpOutMode");

        // b. 下载位置比较数组
        short dataCount = 11;
        NativeLong[] posArray = new NativeLong[dataCount];

        for (int i = 0; i < dataCount; i++) {
            long position = (i + 1) * 1000L + 100L; // 计算位置值
            posArray[i] = new NativeLong(position);  // 为每个元素创建 NativeLong 实例
        }

        // 下载数据
        rtn = NMC_CompXDimensSetData(devHandle, posArray, dataCount, ch);
        checkError(rtn, "NMC_CompXDimensSetData");

        // c. 启动位置比较输出
        rtn = NMC_CompXDimensOnoff(devHandle, (short)1, ch);
        checkError(rtn, "NMC_CompXDimensOnoff");

        // d. 执行运动，触发位置比较
        // 运动第二轴（即位置比较轴）
        rtn = NMC_MtMovePtpAbs(axisHandle, 1.0, 1.0, 0.0, 0.0, 5.0, (short)0, new NativeLong(100000L));
        checkError(rtn, "NMC_MtMovePtpAbs");

        // 可以在此处添加查询状态的代码
        ShortByReference pStatus = new ShortByReference();
        ShortByReference pOutCount = new ShortByReference();
        rtn = NMC_CompXDimensStatus(devHandle, pStatus, pOutCount, ch);
        checkError(rtn, "NMC_CompXDimensStatus");
        System.out.println("位置比较状态 - 运行中: " + pStatus.getValue() + ", 已输出: " + pOutCount.getValue());


    /**
     * 结束测试，关闭设备
    */
        rtn = NMC_MtClose(pAxisHandle);
        checkError(rtn, "NMC_MtClose");
        rtn = NMC_DevClose(pDevHandle);
        checkError(rtn, "NMC_DevClose");

    }
}