export default class MySerialPort  {
  constructor() {
    this.state = {
      portIndex: undefined,
      ports: [],
      isOpen: false,
      writeType: 1,
      readType: 1,
      isScroll: true,
      readValue: [],
      status:false,
      //port参数
      baudRate: "9600",
      dataBits: "8",
      stopBits: "1",
      parity: "none",
      flowControl: "none",
    };
    this.keepReading=false;
    this.getPorts = this.getPorts.bind(this);
    this.handleRequestPort = this.handleRequestPort.bind(this);
    this.handleChildrenChange = this.handleChildrenChange.bind(this);
    this.readText = this.readText.bind(this);
    this.writeText = this.writeText.bind(this);
    this.handleClear = this.handleClear.bind(this);
    this.a2hex = this.a2hex.bind(this);
    this.hex2a = this.hex2a.bind(this);
    this.hex2atostr=this.hex2atostr.bind(this);
    this.reader={};
    this.closed;
  }

  async getPorts() {
    // 获取已授权的全部串口
    let ports = await navigator.serial.getPorts();
    this.setState({
      ports,
    });
  }
  async handleRequestPort() {
    // 请求授权
    try {
      await navigator.serial.requestPort();
      await this.getPorts();
    } catch (e) {
      this.$message.error(e.toString());
    }
  }
  async openPort(portIndex, isOpen,callBack=null) {
    // 打开串口
    let port = this.state.ports[portIndex];
    if (!isOpen) {
      // 关闭串口
      this.keepReading = false;
      this.reader.cancel();
      await this.closed;
      this.handlePortOpen({
        portIndex,
        isOpen,
      });
    } else {
      await port.open({
        baudRate: this.state.baudRate,
        dataBits: this.state.dataBits,
        stopBits: this.state.stopBits,
        parity: this.state.parity,
        flowControl: this.state.flowControl,
      });
      this.handlePortOpen({
        portIndex,
        isOpen,
      });
      this.keepReading = true;
      this.closed=this.readUntilClosed(portIndex,callBack);
    }
  }
  async readUntilClosed(portIndex,callBack=null) {
    let port = this.state.ports[portIndex];
    while (port.readable && this.keepReading) {
      this.reader = port.readable.getReader();
      try {
        let readCache=[]
        while (true) {
          const { value, done } = await this.reader.read();
          if (done) {
            break;
          }
          readCache.push(...value)
          setTimeout(() => {
            if(readCache.length>0){
              this.readText(readCache);
              callBack(readCache)
              readCache=[]
            }
          }, 300);//串口缓存
        }
      } catch (error) {
        this.$message.error(error.toString());
      } finally {
        this.reader.releaseLock();
      }
      await port.close();
    }
  }
  handlePortOpen({ portIndex, isOpen }) {
    // 处理打开串口
    this.setState({
      portIndex,
      isOpen,
    });
  }
  handleChildrenChange(type, value) {
    this.setState({
      [type]: value,
    });
  }
  portWrite(value) {
    return new Promise(async (resolve, reject) => {
      if (!this.state.isOpen) {
        this.$message.error("串口未打开");
        reject();
        return;
      } else {
        let port = this.state.ports[this.state.portIndex];
        const writer = port.writable.getWriter();
        await writer.write(new Uint8Array(value));
        writer.releaseLock();
        resolve(value);
      }
    });
  }
  readText(value) {
    console.log(value, "读取");
    let newValue = this.state.readValue.concat({
      value,
      type: 1,
    });
    this.setState({
      readValue: newValue,
    });
  }
  writeText(value) {
    console.log(value, "写入");
    this.portWrite(value).then((res) => {
      let newValue = this.state.readValue.concat({
        value: res,
        type: 2,
      });
      this.setState({
        readValue: newValue,
      });
    });
  }
  handleClear() {
    this.setState({
      readValue: [],
    });
  }
  componentDidMount() {
    this.getPorts();
  }
  handleState(status) {
    this.setState({
      status,
    });
  }
  setState(obj){
    Object.keys(this.state).forEach(key => {
      if(obj[key]!=undefined){
        this.state[key]=obj[key]
      }
    });
  }
  //字节转字符串
  hex2atostr(arr) {
    return String.fromCharCode.apply(String,arr);
  }
  hex2a(hexx) {
    return String.fromCharCode(hexx);
  }
  //字符转16进制
  a2hex(str) {
    return str.charCodeAt(0);
  }
}