/**
 * @author @thkruz Theodore Kruczek
 * @license AGPL-3.0-or-later
 * @copyright (c) 2025 Kruczek Labs LLC
 *
 * Orbital Object ToolKit is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Affero General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * Orbital Object ToolKit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along with
 * Orbital Object ToolKit. If not, see <http://www.gnu.org/licenses/>.
 */

/* eslint-disable @typescript-eslint/no-loss-of-precision */
/* eslint-disable class-methods-use-this */
import { RungeKuttaAdaptive } from './RungeKuttaAdaptive.js';

// / Runge-Kutta 8(9) adaptive numerical propagator.
export class RungeKutta89Propagator extends RungeKuttaAdaptive {
  private readonly a_ = Float64Array.from([
    0.0, 0.3462e-1, 0.9702435063878044594828361677100617517633e-1, 0.1455365259581706689224254251565092627645, 0.561,
    0.2290079115904850126662751771814700052182, 0.5449920884095149873337248228185299947818, 0.645, 0.48375, 0.6757e-1,
    0.25, 0.6590650618730998549405331618649220295334, 0.8206, 0.9012, 1.0, 1.0,
  ]);
  private readonly b_ = [
    new Float64Array(0),
    Float64Array.from([0.3462e-1]),
    Float64Array.from([-0.389335438857287327017042687229284478532e-1, 0.1359578945245091786499878854939346230295]),
    Float64Array.from([0.3638413148954266723060635628912731569111e-1, 0.0, 0.1091523944686280016918190688673819470733]),
    Float64Array.from([
      2.025763914393969636805657604282571047511, 0.0, -7.638023836496292020387602153091964592952,
      6.173259922102322383581944548809393545442,
    ]),
    Float64Array.from([
      0.5112275589406060872792270881648288397197e-1, 0.0, 0.0, 0.1770823794555021537929910813839068684087,
      0.80277624092225014536138698108025283759e-3,
    ]),
    Float64Array.from([
      0.1316006357975216279279871693164256985334, 0.0, 0.0, -0.2957276252669636417685183174672273730699,
      0.878137803564295237421124704053886667082e-1, 0.62130529752252747743214350056394300261,
    ]),
    Float64Array.from([
      0.7166666666666666666666666666666666666667e-1, 0.0, 0.0, 0.0, 0.0, 0.3305533578915319409260346730051472207728,
      0.2427799754418013924072986603281861125606,
    ]),
    Float64Array.from([
      0.71806640625e-1, 0.0, 0.0, 0.0, 0.0, 0.3294380283228177160744825466257672816401,
      0.1165190029271822839255174533742327183599, -0.34013671875e-1,
    ]),
    Float64Array.from([
      0.4836757646340646986611287718844085773549e-1, 0.0, 0.0, 0.0, 0.0, 0.3928989925676163974333190042057047002852e-1,
      0.1054740945890344608263649267140088017604, -0.2143865284648312665982642293830533996214e-1,
      -0.1041229174627194437759832813847147895623,
    ]),
    Float64Array.from([
      -0.2664561487201478635337289243849737340534e-1, 0.0, 0.0, 0.0, 0.0, 0.3333333333333333333333333333333333333333e-1,
      -0.1631072244872467239162704487554706387141, 0.3396081684127761199487954930015522928244e-1,
      0.1572319413814626097110769806810024118077, 0.215226747803187955230353477879477037696,
    ]),
    Float64Array.from([
      0.3689009248708622334786359863227633989718e-1, 0.0, 0.0, 0.0, 0.0, -0.1465181576725542928653609891758501156785,
      0.2242577768172024345345469822625833796001, 0.2294405717066072637090897902753790803034e-1,
      -0.35850052905728761357394424889330334334e-2, 0.8669223316444385506869203619044453906053e-1,
      0.4383840651968337846196219974168630120572,
    ]),
    Float64Array.from([
      -0.4866012215113340846662212357570395295088, 0.0, 0.0, 0.0, 0.0, -6.304602650282852990657772792012007122988,
      -0.281245618289472564778284183790118418111, -2.679019236219849057687906597489223155566,
      0.518815663924157511565311164615012522024, 1.365353187603341710683633635235238678626,
      5.885091088503946585721274891680604830712, 2.802808786272062889819965117517532194812,
    ]),
    Float64Array.from([
      0.4185367457753471441471025246471931649633, 0.0, 0.0, 0.0, 0.0, 6.724547581906459363100870806514855026676,
      -0.425444280164611790606983409697113064616, 3.343279153001265577811816947557982637749,
      0.617081663117537759528421117507709784737, -0.929966123939932833937749523988800852013,
      -6.099948804751010722472962837945508844846, -3.002206187889399044804158084895173690015,
      0.2553202529443445472336424602988558373637,
    ]),
    Float64Array.from([
      -0.779374086122884664644623040843840506343, 0.0, 0.0, 0.0, 0.0, -13.93734253810777678786523664804936051203,
      1.252048853379357320949735183924200895136, -14.69150040801686878191527989293072091588,
      -0.494705058533141685655191992136962873577, 2.242974909146236657906984549543692874755,
      13.36789380382864375813864978592679139881, 14.39665048665068644512236935340272139005,
      -0.7975813331776800379127866056663258667437, 0.4409353709534277758753793068298041158235,
    ]),
    Float64Array.from([
      2.058051337466886442151242368989994043993, 0.0, 0.0, 0.0, 0.0, 22.35793772796803295519317565842520212899,
      0.90949810997556332745009198137971890783, 35.89110098240264104710550686568482456493,
      -3.442515027624453437985000403608480262211, -4.865481358036368826566013387928704014496,
      -18.90980381354342625688427480879773032857, -34.26354448030451782929251177395134170515,
      1.264756521695642578827783499806516664686, 0.0, 0.0,
    ]),
  ];
  private readonly ch_ = Float64Array.from([
    0.1996996514886773085518508418098868756464e-1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
    2.191499304949330054530747099310837524864, 0.8857071848208438030833722031786358862953e-1,
    0.1140560234865965622484956605091432032674, 0.2533163805345107065564577734569651977347,
    -2.056564386240941011158999594595981300493, 0.340809679901311993516009489422454381283, 0.0, 0.0,
    0.4834231373823958314376726739772871714902e-1,
  ]);
  private readonly c_ = Float64Array.from([
    0.1461197685842315252051541915018784713459e-1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
    -0.391521186233133908941022826728824203081, 0.2310932500289506415909675644868993669908,
    0.1274766769992852382560589467488989175618, 0.2246434176204157731566981937082069688984,
    0.5684352689748512932705226972873692126743, 0.5825871557215827200814768021863420902155e-1,
    0.1364317403482215641609022744494239843327, 0.3057013983082797397721005067920369646664e-1, 0.0,
  ]);

  get a(): Float64Array {
    return this.a_;
  }

  get b(): Float64Array[] {
    return this.b_;
  }

  get ch(): Float64Array {
    return this.ch_;
  }

  get c(): Float64Array {
    return this.c_;
  }

  get order(): number {
    return 8;
  }
}
