text: "use strict";
  /**
   * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
   *
   * @author David Sehnal <david.sehnal@gmail.com>
   * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
   */
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.parseMol = exports.handlePropertiesBlock = exports.handleFormalCharges = exports.handleBonds = exports.handleAtoms = exports.formalChargeMapper = void 0;
  var tslib_1 = require("tslib");
  var db_1 = require("../../../mol-data/db");
  var mol_task_1 = require("../../../mol-task");
  var token_1 = require("../common/text/column/token");
  var tokenizer_1 = require("../common/text/tokenizer");
  var result_1 = require("../result");
  /*
      The atom lines in a .mol file have the following structure:
  
      xxxxx.xxxxyyyyy.yyyyzzzzz.zzzz aaaddcccssshhhbbbvvvHHHrrriiimmmnnneee
      ---------------------------------------------------------------------
  
      Below is a breakdown of each component and its start/end indices:
  
      xxxxx.xxxx  (X COORDINATE, 1-10)
      yyyyy.yyyy  (Y COORDINATE, 10-20)
      zzzzz.zzzz  (Z COORDINATE, 20-30)
      _           (30 IS EMPTY)
      aaa         (ATOM SYMBOL, 31-34)
      dd          (MASS DIFF, 34-36)
      ccc         (FORMAL CHARGE, 36-39)
      sss         (ATOM STEREO PARITY, 39-42)
      hhh         (HYDROGEN COUNT+1, 42-45)
      bbb         (STEREO CARE BOX, 45-48)
      vvv         (VALENCE, 48-51)
      HHH         (H0 DESIGNATOR, 51-54)
      rrr         (UNUSED, 54-57)
      iii         (UNUSED, 57-60)
      mmm         (ATOM-ATOM MAPPING NUMBER, 60-63)
      nnn         (INVERSION/RETENTION FLAG, 63-66)
      eee         (EXACT CHANGE FLAG, 66-69)
  */
  /**
   * @param key - The value found at the atom block.
   * @returns The actual formal charge based on the mapping.
   */
  function formalChargeMapper(key) {
      switch (key) {
          case 7: return -3;
          case 6: return -2;
          case 5: return -1;
          case 0: return 0;
          case 3: return 1;
          case 2: return 2;
          case 1: return 3;
          case 4: return 0;
          default:
              console.error("Value ".concat(key, " is outside the 0-7 range, defaulting to 0."));
              return 0;
      }
  }
  exports.formalChargeMapper = formalChargeMapper;
  function handleAtoms(tokenizer, count) {
      var x = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      var y = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      var z = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      var type_symbol = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      var formal_charge = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      for (var i = 0; i < count; ++i) {
          tokenizer_1.Tokenizer.markLine(tokenizer);
          var s = tokenizer.tokenStart, position = tokenizer.position;
          tokenizer_1.Tokenizer.trim(tokenizer, s, s + 10);
          tokenizer_1.TokenBuilder.addUnchecked(x, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer_1.Tokenizer.trim(tokenizer, s + 10, s + 20);
          tokenizer_1.TokenBuilder.addUnchecked(y, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer_1.Tokenizer.trim(tokenizer, s + 20, s + 30);
          tokenizer_1.TokenBuilder.addUnchecked(z, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer_1.Tokenizer.trim(tokenizer, s + 31, s + 34);
          tokenizer_1.TokenBuilder.addUnchecked(type_symbol, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer_1.Tokenizer.trim(tokenizer, s + 36, s + 39);
          tokenizer_1.TokenBuilder.addUnchecked(formal_charge, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer.position = position;
      }
      return {
          count: count,
          x: (0, token_1.TokenColumnProvider)(x)(db_1.Column.Schema.float),
          y: (0, token_1.TokenColumnProvider)(y)(db_1.Column.Schema.float),
          z: (0, token_1.TokenColumnProvider)(z)(db_1.Column.Schema.float),
          type_symbol: (0, token_1.TokenColumnProvider)(type_symbol)(db_1.Column.Schema.str),
          formal_charge: (0, token_1.TokenColumnProvider)(formal_charge)(db_1.Column.Schema.int)
      };
  }
  exports.handleAtoms = handleAtoms;
  function handleBonds(tokenizer, count) {
      var atomIdxA = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      var atomIdxB = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      var order = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
      for (var i = 0; i < count; ++i) {
          tokenizer_1.Tokenizer.markLine(tokenizer);
          var s = tokenizer.tokenStart, position = tokenizer.position;
          tokenizer_1.Tokenizer.trim(tokenizer, s, s + 3);
          tokenizer_1.TokenBuilder.addUnchecked(atomIdxA, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer_1.Tokenizer.trim(tokenizer, s + 3, s + 6);
          tokenizer_1.TokenBuilder.addUnchecked(atomIdxB, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer_1.Tokenizer.trim(tokenizer, s + 6, s + 9);
          tokenizer_1.TokenBuilder.addUnchecked(order, tokenizer.tokenStart, tokenizer.tokenEnd);
          tokenizer.position = position;
      }
      return {
          count: count,
          atomIdxA: (0, token_1.TokenColumnProvider)(atomIdxA)(db_1.Column.Schema.int),
          atomIdxB: (0, token_1.TokenColumnProvider)(atomIdxB)(db_1.Column.Schema.int),
          order: (0, token_1.TokenColumnProvider)(order)(db_1.Column.Schema.int)
      };
  }
  exports.handleBonds = handleBonds;
  function handleFormalCharges(tokenizer, lineStart, formalCharges) {
      tokenizer_1.Tokenizer.trim(tokenizer, lineStart + 6, lineStart + 9);
      var numOfCharges = parseInt(tokenizer_1.Tokenizer.getTokenString(tokenizer));
      for (var i = 0; i < numOfCharges; ++i) {
          /*
          M  CHG  3   1  -1   2   0   2  -1
                  |   |   |   |   |
                  |   |   |   |   |__charge2 (etc.)
                  |   |   |   |
                  |   |   |   |__atomIdx2
                  |   |   |
                  |   |   |__charge1
                  |   |
                  |   |__atomIdx1 (cursor at position 12)
                  |
                  |___numOfCharges
          */
          var offset = 9 + (i * 8);
          tokenizer_1.Tokenizer.trim(tokenizer, lineStart + offset, lineStart + offset + 4);
          var _atomIdx = tokenizer_1.Tokenizer.getTokenString(tokenizer);
          formalCharges.atomIdx.push(+_atomIdx);
          tokenizer_1.Tokenizer.trim(tokenizer, lineStart + offset + 4, lineStart + offset + 8);
          var _charge = tokenizer_1.Tokenizer.getTokenString(tokenizer);
          formalCharges.charge.push(+_charge);
      }
      /* Once the line is read, move to the next one. */
      tokenizer_1.Tokenizer.eatLine(tokenizer);
  }
  exports.handleFormalCharges = handleFormalCharges;
  /** Call an appropriate handler based on the property type.
   * (For now it only calls the formal charge handler, additional handlers can
   * be added for other properties.)
   */
  function handlePropertiesBlock(tokenizer) {
      var _atomIdx = [];
      var _charge = [];
      var _formalCharges = { atomIdx: _atomIdx, charge: _charge };
      while (tokenizer.position < tokenizer.length) {
          var s = tokenizer.position;
          tokenizer_1.Tokenizer.trim(tokenizer, s + 3, s + 6);
          var propertyType = tokenizer_1.Tokenizer.getTokenString(tokenizer);
          if (propertyType === 'END')
              break;
          tokenizer_1.Tokenizer.eatLine(tokenizer);
          switch (propertyType) {
              case 'CHG':
                  handleFormalCharges(tokenizer, s, _formalCharges);
                  break;
              default:
                  break;
          }
      }
      var formalCharges = {
          atomIdx: db_1.Column.ofIntArray(_formalCharges.atomIdx),
          charge: db_1.Column.ofIntArray(_formalCharges.charge)
      };
      return formalCharges;
  }
  exports.handlePropertiesBlock = handlePropertiesBlock;
  function parseInternal(data) {
      var tokenizer = (0, tokenizer_1.Tokenizer)(data);
      var title = tokenizer_1.Tokenizer.readLine(tokenizer).trim();
      var program = tokenizer_1.Tokenizer.readLine(tokenizer).trim();
      var comment = tokenizer_1.Tokenizer.readLine(tokenizer).trim();
      var counts = tokenizer_1.Tokenizer.readLine(tokenizer);
      var atomCount = +counts.substr(0, 3), bondCount = +counts.substr(3, 3);
      var atoms = handleAtoms(tokenizer, atomCount);
      var bonds = handleBonds(tokenizer, bondCount);
      var formalCharges = handlePropertiesBlock(tokenizer);
      var result = {
          title: title,
          program: program,
          comment: comment,
          atoms: atoms,
          bonds: bonds,
          formalCharges: formalCharges,
      };
      return result_1.ReaderResult.success(result);
  }
  function parseMol(data) {
      var _this = this;
      return mol_task_1.Task.create('Parse Mol', function () { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
          return (0, tslib_1.__generator)(this, function (_a) {
              return [2 /*return*/, parseInternal(data)];
          });
      }); });
  }
  exports.parseMol = parseMol;
  //# sourceMappingURL=parser.js.map