package com.example;

import static com.example.mtnlib.nmc_lib20.*;
import static com.example.mtnlib.nmc_lib20_ext.*;
import static com.example.mtnlib.nmc_lib20_oem.*;
import static com.example.mtnlib.nmc_lib20_err.*;
import com.example.mtnlib.nmc_lib20_com.*;
import com.sun.jna.ptr.*;

public class Main {
    // 错误处理工具类
    private static class ErrorHandler {
        /**
         * 检查返回值并处理错误
         * @param rtn 函数返回值
         * @throws RuntimeException 如果返回值不是0(成功)
         */
        public static void checkError(short rtn) {
            if (rtn != 0) {
                throw new RuntimeException(String.format("操作失败，错误代码: %d", rtn));
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("单轴状态查询测试开始...");

        short devNum = 0;       // 设备编号，从0开始
        short axisNum = 0;      // 轴编号，从0开始
        HAND devHandle= null ;        // 设备句柄
        HAND axisHandle= null ;       // 轴句柄

        try {
            // 打开控制器
            PHAND pDevHandle = new PHAND();
            short rtn = NMC_DevOpen(devNum, pDevHandle);
            ErrorHandler.checkError(rtn);
            System.out.println("打开设备 - 成功");
            devHandle = pDevHandle.getHandle();
            
            // 打开轴
            PHAND pAxisHandle = new PHAND();
            rtn = NMC_MtOpen(devHandle, axisNum, pAxisHandle);
            ErrorHandler.checkError(rtn);
            System.out.println("打开轴 - 成功");
            axisHandle = pAxisHandle.getHandle();

            //打开轴使能(根据实际情况使用)
            rtn = NMC_MtSetSvOn(axisHandle);
            ErrorHandler.checkError(rtn);
            System.out.println("伺服使能 - 成功");


            // 状态查询循环
            System.out.println("\n开始状态查询循环(按Ctrl+C退出)...");

                // 轴的状态标志
                ShortByReference axisSts = new ShortByReference();
                
                // 获取轴状态
                rtn = NMC_MtGetSts(axisHandle, axisSts);
                ErrorHandler.checkError(rtn);

                // 解析状态位
                boolean isRunning = (axisSts.getValue() & BIT_AXIS_BUSY) != 0;              //取bit0,0静止,1运动
                boolean isArrived = (axisSts.getValue() & BIT_AXIS_POSREC) != 0;            //取bit1,位置到达,0,未到达,1到达      
                boolean isError = (axisSts.getValue() & BIT_AXIS_MVERR) != 0;               //取bit2,运动是否出错,0,未出错,1,出错
                boolean isAxisOn = (axisSts.getValue() & BIT_AXIS_SVON) != 0;               //取bit3,是否使能中
                boolean isAlarm = (axisSts.getValue() & BIT_AXIS_ALM) != 0;                 //取bit6,正向限位是否触发
                boolean isPosLimit = (axisSts.getValue() & BIT_AXIS_LMTP) != 0;             //取bit7,负向限位是否触发
                boolean isNegLimit = (axisSts.getValue() & BIT_AXIS_LMTN) != 0;             //取bit8,正向软限位是否触发
                boolean isPosSoftLimit = (axisSts.getValue() & BIT_AXIS_SOFTPOSLMT) != 0;   //取bit9,负向软限位是否触发
                boolean isNegSoftLimit = (axisSts.getValue() & BIT_AXIS_SOFTNEGLMT) != 0;   //取bit10,驱动器是否报警
                boolean isPosError = (axisSts.getValue() & BIT_AXIS_POSERR) != 0;           //取bit11,位置是否超过误差极限

                // 轴运动之前，或者轴报错,调用清除轴状态的指令
                rtn = NMC_MtClrError(axisHandle);
                ErrorHandler.checkError(rtn);
                System.out.println("清除错误状态 - 成功");

	/**********************************分割线**********************************/

	/*****下面获取为单轴的状态，要同时获取多个轴的状态，可使用for循环操作******/
                // 获取位置和速度信息
                NativeLongByReference prfPos = new NativeLongByReference(); 
                NativeLongByReference encPos = new NativeLongByReference(); 
                DoubleByReference prfVel = new DoubleByReference();         
                DoubleByReference encVel = new DoubleByReference();         

                rtn = NMC_MtGetPrfPos(axisHandle, prfPos);          // 规划位置
                ErrorHandler.checkError(rtn);
                rtn = NMC_MtGetEncPos(axisHandle, encPos);          // 实际位置
                ErrorHandler.checkError(rtn);
                rtn = NMC_MtGetPrfVel(axisHandle, prfVel);          // 规划速度
                ErrorHandler.checkError(rtn);
                rtn = NMC_GetEncVel(axisHandle, (short) 0, encVel); // 实际速度
                ErrorHandler.checkError(rtn);

                // 打印状态信息
                System.out.println("\n===== 轴状态信息 =====");
                System.out.printf("规划位置: %d\n", prfPos.getValue().longValue());
                System.out.printf("实际位置: %d\n", encPos.getValue().longValue());
                System.out.printf("规划速度: %.2f\n", prfVel.getValue());
                System.out.printf("实际速度: %.2f\n", encVel.getValue());
                System.out.printf("状态位: %d (0x%04X, 二进制: %s)\n", axisSts.getValue() & 0xFFFF, axisSts.getValue() & 0xFFFF,Integer.toBinaryString(axisSts.getValue() & 0xFFFF));
                System.out.println("  运动状态: " + (isRunning ? "运动中" : "静止"));
                System.out.println("  位置到达: " + (isArrived ? "已到达" : "未到达"));
                System.out.println("  错误状态: " + (isError ? "有错误" : "正常"));
                System.out.println("  使能状态: " + (isAxisOn ? "已使能" : "未使能"));
                System.out.println("  报警状态: " + (isAlarm ? "有报警" : "无报警"));
                System.out.println("  位置误差: " + (isPosError ? "过大" : "正常"));
                System.out.println("  限位状态: " + 
                    (isPosLimit ? "正限位触发 " : "") + 
                    (isNegLimit ? "负限位触发 " : "") + 
                    (!isPosLimit && !isNegLimit ? "无限位触发" : ""));
                System.out.println("  软限位状态: " + 
                    (isPosSoftLimit ? "正软限位触发 " : "") + 
                    (isNegSoftLimit ? "负软限位触发 " : "") + 
                    (!isPosSoftLimit && !isNegSoftLimit ? "无软限位触发" : ""));
                // /**********************************分割线**********************************/
                // // 添加获取所有轴信息的代码
                // TAxisStsPack12Ex stspack = new TAxisStsPack12Ex(); // 控制器所有轴信息打包结构体
                // rtn = NMC_MtGetStsPack12Ex(devHandle, stspack); // 一次性获取所有轴信息
                // ErrorHandler.checkError(rtn);
                // System.out.println("成功获取所有轴状态信息");
        } catch (Exception e) {
            System.err.println("测试过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 确保资源被释放
            System.out.println("\n释放资源...");
            try {
                System.out.println("资源释放完成");
            } catch (Exception e) {
                System.err.println("资源释放时发生错误: " + e.getMessage());
            }
        }
    }
}