{
  Copyright (C)
  2026 - Uladzimir Karpenka, EW8BAK

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program 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 General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
}

unit FMRepeater;

{ FM repeater offset helpers — constants, default offsets, auto-direction logic. }

{$mode objfpc}{$H+}

interface

const
  RPT_NONE  = 0;
  RPT_MINUS = 1;
  RPT_PLUS  = 2;

  RPT_2M_BEGIN     = 144000000.0;
  RPT_2M_END       = 148000000.0;
  RPT_70CM_BEGIN   = 430000000.0;
  RPT_70CM_END     = 440000000.0;
  RPT_DEFAULT_2M   =   600000.0;  // 0.600 MHz
  RPT_DEFAULT_70CM = 7600000.0;   // 7.600 MHz

  // European 2m repeater input segment: auto-enable minus direction
  RPT_AUTO_MINUS_LO = 145600000.0;  // 145.600 MHz
  RPT_AUTO_MINUS_HI = 145787500.0;  // 145.7875 MHz

  // CTCSS tones (38 standard tones). Здесь (а не в MainForm), чтобы таблица
  // была доступна TRadioController для FDSPEngine.SetTXCTCSS. Имена тонов
  // (CTCSS_NAMES) остаются в MainForm — это UI-метки выпадающего списка.
  CTCSS_COUNT = 38;
  CTCSS_TONES: array[0..CTCSS_COUNT-1] of Double = (
    67.0,  71.9,  74.4,  77.0,  79.7,  82.5,  85.4,  88.5,  91.5,  94.8,
    97.4,  100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8,
    136.5, 141.3, 146.2, 151.4, 156.7, 162.2, 167.9, 173.8, 179.9, 186.2,
    192.8, 203.5, 210.7, 218.1, 225.7, 233.6, 241.8, 250.3);

{ Returns default offset (Hz) for the given visible frequency.
  70 cm band → 7.600 MHz; everything else → 0.600 MHz. }
function RptDefaultOffsetHz(FreqHz: Double): Double;

{ Returns RPT_MINUS when FreqHz falls in the 2 m auto-minus segment,
  RPT_NONE otherwise. }
function RptAutoDir(FreqHz: Double): Integer;

{ Formats OffsetHz as MHz with 3 decimal places, e.g. "0.600". }
function RptFormatOffset(OffsetHz: Double): string;

{ Parses a MHz string ("0.600", "7.6", "7,600") to Hz.
  Returns 0 on parse error or out-of-range value. }
function RptParseOffset(const S: string): Double;

implementation

uses SysUtils;

function RptDefaultOffsetHz(FreqHz: Double): Double;
begin
  if (FreqHz >= RPT_70CM_BEGIN) and (FreqHz <= RPT_70CM_END) then
    Result := RPT_DEFAULT_70CM
  else
    Result := RPT_DEFAULT_2M;
end;

function RptAutoDir(FreqHz: Double): Integer;
begin
  if (FreqHz >= RPT_AUTO_MINUS_LO) and (FreqHz <= RPT_AUTO_MINUS_HI) then
    Result := RPT_MINUS
  else
    Result := RPT_NONE;
end;

function RptFormatOffset(OffsetHz: Double): string;
begin
  Result := Format('%.3f', [OffsetHz / 1000000.0]);
end;

function RptParseOffset(const S: string): Double;
var
  V:    Double;
  Code: Integer;
  Norm: string;
begin
  Norm := StringReplace(Trim(S), ',', '.', [rfReplaceAll]);
  Val(Norm, V, Code);
  if (Code = 0) and (V > 0.0) and (V <= 100.0) then
    Result := V * 1000000.0
  else
    Result := 0.0;
end;

end.
