unit YasForm;
{
   Author:  Vesa Lappalainen
   Date:    30.12.1996
   Changes: 11.01.1997
              + leds
   Missing:
     -- run command and reverse command two way and bit places possible
        to define
     -- Store params-command   

     -- Run command by bitfield param
     -- editing bitparams
     -- reading Leds from ini-file
}
interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  KParams, StdCtrls, ExtCtrls, kComp, ComCtrls, kbar, KYasPar, KModbus,
  KButtons, KParam, Gauges, kRndled, savepos, kinicomp, YasExtContact;

const MAXVALUES=3;

type PTForm = ^TForm;

type
  TValueBar = class (TObject)
  public
    v:TkParam;
    b:TGauge;
    max:double;
    maxi:integer;
    vali:integer;
    procedure SetValue(d:double);
    property Value:double write SetValue;
  end;

type
  TFormYas = class(TForm)
    GroupBoxRun: TGroupBox;
    kTrackBarHz: TkTrackBar;
    PanelLeft: TPanel;
    LabelPortText: TLabel;
    ButtonParams: TButton;
    BYasBack: TkSpeedButton;
    BYasFwd: TkSpeedButton;
    BYasRun: TkSpeedButton;
    CounterMin: TCounter;
    CounterMax: TCounter;
    Label0: TLabel;
    CounterHz: TkParam;
    TimerRead: TTimer;
    PanelMeters: TPanel;
    kParamFreq: TkParam;
    GaugeFreq: TGauge;
    kParamCurA: TkParam;
    kParamOutV: TkParam;
    GaugeCurA: TGauge;
    GaugeOutV: TGauge;
    GaugeRef: TGauge;
    kParamRef: TkParam;
    GroupBoxOutput: TGroupBox;
    GroupBoxInput: TGroupBox;
    GroupBoxFault: TGroupBox;
    LedFault: TkRndLed;
    CBReset: TCheckBox;
    ParamSlave: TkParam;
    SavePos1: TSavePos;
    LabelPort: TButton;
    CBEnabled: TkCheckBox;
    EditIniModel: TEditIni;
    LabelModel: TLabel;
    S1: TFrameYasExtContact;
    M1: TFrameYasExtContact;
    PanelTopLeft: TPanel;
    PanelExt: TPanel;
    PanelOutput: TPanel;
    PanelButtons: TPanel;
    CheckBoxUpdate: TCheckBox;
    ButtonShowCom: TButton;
    ButtonOK: TButton;
    PanelButtonsBottom: TPanel;
    ButtonStoreRam: TButton;
    ButtonStoreEprom: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ButtonParamsClick(Sender: TObject);
    procedure kTrackBarHzChange(Sender: TObject); virtual;
    procedure CounterHzClick(Sender: TObject); virtual;
    procedure BYasStopClick(Sender: TObject);
    procedure SetHz(hz:double; run:boolean);
    procedure Stop;
    procedure UpdateMinMax;
    procedure CheckButtons(Sender: TObject; down:boolean);
    procedure BYasFwdMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BYasBackMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BYasRunMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BYasRunMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure kParamFreqClick(Sender: TObject);
    procedure TimerReadTimer(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure CreateValues;
    procedure UpdateValues;
    procedure CheckBoxMAMCClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure CheckBoxS1Click(Sender: TObject);
    procedure ButtonOKClick(Sender: TObject);
    procedure ReadIni;
    procedure WriteIni;
    procedure EditS1Change(Sender: TObject);
    procedure CBResetClick(Sender: TObject);
    procedure CheckBoxUpdateClick(Sender: TObject);
    procedure ButtonShowComClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    function ParamSlaveAfterAsk(Sender: TObject; var val: Double): Boolean;
    procedure LabelPortClick(Sender: TObject);
    procedure CBEnabledClick(Sender: TObject);
    procedure ButtonStoreRamClick(Sender: TObject);
    procedure ButtonStoreEpromClick(Sender: TObject);
  private
    params:TYasParams;
    formptr : PTForm;
    Changes : integer;
    values : array [0..MAXVALUES] of TValueBar;
    OutWIndex : integer;
    InWIndex : integer;
    OutRIndex : integer;
    InRIndex : integer;
    ExtS : array of TFrameYasExtContact;
    ExtM : array of TFrameYasExtContact;
  protected
    function GetValueIni:string; virtual;
  public
    procedure Loaded; override;
    constructor Create2(form:PTForm; par:TYasParams);
    property ValueIni:string read GetValueIni;
  end;

  function GetYasModel(InvName:string):string;

implementation
  uses IniFiles,IniName, kstring;

{$R *.DFM}

function GetYasModel(InvName:string):string;
var Ini : TIniFile;
begin
  Ini := TIniFile.Create(GetIniName(''));
  Result := Ini.ReadString('FormYas'+InvName+'-Params','Model','');
  Ini.Free;
  if Length(result)<3 then Result := UpperCase(Result);
  if ( Result = 'P' ) then Result := ''; // DownWard compatibility
end;


procedure TValueBar.SetValue(d:double);
begin
  if ( v <> NIL ) then v.Value := d;
  if ( max <= 0 ) or ( b = NIL ) then exit;
  b.Progress := round(abs(d)*100.0/max);
end;

function TFormYas.GetValueIni:string;
begin
  Result := Params.ValueIniName;
end;

procedure TFormYas.ReadIni;
var i:integer;
    Ini : TIniFile;
begin
  for i:=0 to Params.InCount-1 do with ExtS[i].Led do begin IniName := ValueIni; ReadInifile; end;
  for i:=0 to Params.OutCount-1 do with ExtM[i].Led do begin IniName := ValueIni; ReadInifile; end;
  LedFault.IniName := ValueIni; LedFault.ReadInifile;

  Ini := TIniFile.Create(Valueini);
  for i:=0 to Params.InCount-1 do
    ExtS[i].Edit.Text := Ini.ReadString('ContactNames',ExtS[i].Caption,ExtS[i].Text);
  for i:=0 to Params.OutCount-1 do
    ExtM[i].Text := Ini.ReadString('ContactNames',ExtM[i].Caption,ExtM[i].Text);
  Ini.Free;
end;

procedure TFormYas.WriteIni;
var i:integer;
    Ini : TIniFIle;
begin
  Ini := TIniFile.Create(Valueini);
  for i:=0 to Params.InCount-1 do
    Ini.WriteString('ContactNames',ExtS[i].Caption,ExtS[i].Text);
  for i:=0 to Params.OutCount-1 do
    Ini.WriteString('ContactNames',ExtM[i].Caption,ExtM[i].Text);
  Ini.Free;
end;

procedure TFormYas.CreateValues;
var i:integer; s:string;
begin
  for i:=0 to MAXVALUES do
    values[i] := TValueBar.Create;

  values[0].v := kParamFreq;
  values[0].b := GaugeFreq;
  values[0].max := 100;
  values[0].maxi := -1;
  values[0].vali := params.GetIndex(params.NameReadHz);

  values[1].v := kParamCurA;
  values[1].b := GaugeCurA;
  values[1].max := 100;
  values[1].maxi := params.GetIndex(params.NameMaxA);
  values[1].vali := params.GetIndex(params.NameReadA);

  values[2].v := kParamOutV;
  values[2].b := GaugeOutV;
  values[2].max := 100;
  values[2].maxi := params.GetIndex(params.NameMaxV);
  values[2].vali := params.GetIndex(params.NameReadV);

  values[3].v := kParamRef;
  values[3].b := GaugeRef;
  values[3].max := 100;
  values[3].maxi := -1;
  values[3].vali := params.GetIndex(params.NameFreqRef);

  s := Params.InputNames;
  SetLength(ExtS,Params.InCount);
  ExtS[0] := S1; S1.CTag := 0;
  for i:=1 to Params.InCount-1 do begin
    ExtS[i] := TFrameYasExtContact.Create(S1.Owner);
    ExtS[i].Parent := S1.Parent;
    ExtS[i].Top := 1000;
    ExtS[i].Align := alTop;
    ExtS[i].CloneSettings(S1);
    ExtS[i].Name := 'ExtS'+IntToStr(i+1);
    ExtS[i].CTag := i;
  end;

  for i:=0 to Params.InCount-1 do
    ExtS[i].Caption := Separate(s,',');

  for i:=0 to Params.InWriteStart-1 do
    ExtS[i].CheckBox.Enabled := false;

  GroupBoxInput.Height := (Params.InCount+1) * S1.Height;

  SetLength(ExtM,Params.OutCount);
  s := Params.OutputNames;
  ExtM[0] := M1;
  for i:=1 to Params.OutCount-1 do begin
    ExtM[i] := TFrameYasExtContact.Create(M1.Owner);
    ExtM[i].Parent := M1.Parent;
    ExtM[i].Top := 1000;
    ExtM[i].Align := alTop;
    ExtM[i].CloneSettings(M1);
    ExtM[i].Name := 'ExtM'+IntToStr(i+1);
    ExtM[i].CTag := i;
  end;

  for i:=0 to Params.OutCount-1 do
    ExtM[i].Caption := Separate(s,',');

  GroupBoxOutput.Height := (Params.OutCount+1) * M1.Height;


  ReadIni();
end;

procedure TFormYas.UpdateMinMax;
begin
  CounterMax.Value := params.ReadMaxHz;
  CounterMin.Value := -CounterMax.Value;
  kTrackBarHz.Max := trunc(CounterMax.Value*10);
  kTrackBarHz.Min := trunc(CounterMin.Value*10);
  values[0].max := abs(CounterHz.Value);
  values[1].max := params.Value(values[1].maxi);
  values[2].max := params.Value(values[2].maxi);
  values[3].max := CounterMax.Value;
end;

procedure TFormYas.UpdateValues;
var bits,i:integer;
begin
  CBEnabled.Checked := Params.Enabled;
  values[0].max := abs(CounterHz.Value);
  for i:=0 to MAXVALUES do begin
    values[i].SetValue(params.ReadValue(values[i].vali));
    if (params.LastError <> '' ) then begin
      CheckBoxUpdate.Checked := false;
      Exit;
    end;
  end;

  bits := Round(params.ReadValue(InWIndex));
  CBReset.Checked := ( bits and Params.ResetBitValue ) <> 0;
  bits := bits shr Params.InWriteShift;
  for i:=Params.InWriteStart to Params.InCount-1 do begin
    ExtS[i].Checked := ( bits and 1 ) = 1;
    bits := bits shr 1;
  end;

  bits := Round(params.ReadValue(InRIndex));
  bits := bits shr Params.InReadShift;
  for i:=0 to Params.InCount-1 do begin
    ExtS[i].LedOn := ( bits and 1 ) = 1;
    bits := bits shr 1;
  end;

  bits := Round(params.ReadValue(OutWIndex));
  bits := bits shr Params.OutWriteShift;
  for i:=0 to Params.OutCount-1 do begin
    ExtM[i].Checked := ( bits and 1 ) = 1;
    bits := bits shr 1;
  end;

  bits := Round(params.ReadValue(OutRIndex));
  LedFault.LedOn := ( bits and 8 ) <> 0;
  bits := bits shr Params.OutReadShift;
  for i:=0 to Params.OutCount-1 do begin
    ExtM[i].LedOn := ( bits and 1 ) = 1;
    bits := bits shr 1;
  end;

end;

procedure TFormYas.FormDestroy(Sender: TObject);
var i:integer;
begin
  formptr^ := NIL;
  if  ( Changes > 0 ) then WriteIni;
  for i:=0 to MAXVALUES do
    values[i].free;
end;

procedure TFormYas.FormCreate(Sender: TObject);
begin
  TimerRead.Enabled := false;
  Changes := 0;



  LabelPort.Caption := IntToStr(Params.Modbus.Port);
//  Top := 0;
//  Left := 0;

  CreateValues;
  UpdateMinMax;
  InWIndex  := params.GetIndex(params.NameInWrite);
  OutWIndex := params.GetIndex(params.NameOutWrite);
  InRIndex  := params.GetIndex(params.NameInRead);
  OutRIndex := params.GetIndex(params.NameOutRead);
  CBEnabled.Checked := Params.Enabled;
  TimerRead.Enabled := CheckBoxUpdate.Checked;
end;


procedure TFormYas.ButtonParamsClick(Sender: TObject);
begin
  params.Edit;
end;

procedure TFormYas.SetHz(hz:double; run:boolean);
begin
  if ( run ) then
    hz := params.WriteReadHz(hz)
  else begin params.WriteHz(hz);  hz := params.ReadHz; end;
  CounterHZ.Value := hz;
  kTrackBarHz.Position := trunc(-hz*10);
end;

procedure TFormYas.kTrackBarHzChange(Sender: TObject);
var hz:double;
begin
  with ( Sender as TkTrackBar ) do hz := -Position/10.0;
  SetHz(hz,BYasRun.Down);
end;

procedure TFormYas.CounterHzClick(Sender: TObject);
begin
  UpdateMinMax;
  CounterHz.MaxValue := CounterMax.Value;
  CounterHz.MinValue := CounterMin.Value;
  CounterHz.Ask;
  SetHz(CounterHz.Value,BYasRun.Down);
end;

procedure TFormYas.Stop;
begin
  Params.Stop;
  BYasRun.Down := false;
  BYasBack.Down := false;
  BYasFwd.Down := false;
end;

procedure TFormYas.BYasStopClick(Sender: TObject);
begin
  Stop;
end;

procedure TFormYas.CheckButtons(Sender: TObject; down:boolean);
begin
  if ( ( Sender = BYasBack ) and BYasRun.Down )  or
     ( ( Sender = BYasFwd  ) and BYasRun.Down ) then begin
    Stop;
    Exit;
  end;

  if ( Sender = BYasBack ) and down then
    SetHZ(-abs(CounterHZ.Value),true)
  else if ( Sender = BYasFwd ) and down then
    SetHZ(abs(CounterHZ.Value),true)
  else begin
    params.stop;
    SetHZ(CounterHZ.Value,false);
  end;
end;

procedure TFormYas.BYasFwdMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  CheckButtons(Sender,true);
end;

procedure TFormYas.BYasBackMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  CheckButtons(Sender,false);
end;

procedure TFormYas.BYasRunMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ( not BYasRun.Down ) then SetHz(CounterHZ.Value,true);
end;

procedure TFormYas.BYasRunMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ( BYasRun.Down ) then begin
    Params.Stop;
    SetHz(CounterHZ.Value,false);
  end;
end;

procedure TFormYas.kParamFreqClick(Sender: TObject);
begin
  //
end;

procedure TFormYas.TimerReadTimer(Sender: TObject);
begin
  TimerRead.Enabled := false;
  UpdateValues;
  TimerRead.Enabled := CheckBoxUpdate.Checked;
end;

procedure TFormYas.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  TimerRead.Enabled := false;
  Stop;
  if ( FormPtr <> NIL ) then FormPtr^ := NIL;
  Release;
end;

procedure TFormYas.CheckBoxMAMCClick(Sender: TObject);
var cb:TCheckBox;
begin
  cb := Sender as TCheckBox;
  params.WriteBit(OutWIndex,cb.tag+Params.OutWriteShift,cb.Checked);
end;

procedure TFormYas.CheckBoxS1Click(Sender: TObject);
var cb:TCheckBox;
begin
  cb := Sender as TCheckBox;
  params.WriteBit(InWIndex,cb.tag+Params.InWriteShift-Params.InWriteStart,cb.Checked);
end;

procedure TFormYas.ButtonOKClick(Sender: TObject);
begin
  Close;
end;

procedure TFormYas.EditS1Change(Sender: TObject);
begin
  Inc(Changes);
end;

procedure TFormYas.CBResetClick(Sender: TObject);
begin
//  params.WriteValue(InWIndex,8*Ord((Sender as TCheckBox).Checked));
  params.Reset;
  (Sender as TCheckBox).Checked := false;
end;

procedure TFormYas.CheckBoxUpdateClick(Sender: TObject);
begin
  TimerRead.Enabled := (Sender as TCheckBox).Checked;
end;

procedure TFormYas.Loaded;
begin
  Name := 'FormYas'+Params.FormName;
  Caption := Params.FormName + ' - ' + Params.Model;
end;

constructor TFormYas.Create2(form:PTForm; par:TYasParams);
begin
  Params := par;
  formptr := form;
  inherited Create(NIL);
//  Params.Slave := trunc(ParamSlave.Value);
  ParamSlave.Value := Params.Slave;
end;


procedure TFormYas.ButtonShowComClick(Sender: TObject);
begin
  Params.ShowErrors;
end;

procedure TFormYas.FormShow(Sender: TObject);
begin
  TimerRead.Enabled := CheckBoxUpdate.Checked;
end;

function TFormYas.ParamSlaveAfterAsk(Sender: TObject;
  var val: Double): Boolean;
begin
  Params.Slave := Trunc(val);
  Result := true;
end;

procedure TFormYas.LabelPortClick(Sender: TObject);
begin
  params.ModbusSlave.Modbus.com.ShowModal;
  LabelPort.Caption := IntToStr(Params.Modbus.Port);
end;

procedure TFormYas.CBEnabledClick(Sender: TObject);
begin
  params.Enabled := CBEnabled.Checked;
end;

procedure TFormYas.ButtonStoreRamClick(Sender: TObject);
begin
  Params.StoreRam;
end;

procedure TFormYas.ButtonStoreEpromClick(Sender: TObject);
begin
  Params.StoreEEPROM;
end;

end.
