// Delphi XE2 source

library sunset;

uses
  SysUtils,
  Windows,
  Classes,
  System.DateUtils,
  sunset_calc in 'sunset_calc.pas';

{$R *.RES}

Const  Inputs = 5;  // number of inputs
       Outputs = 3; // number of outputs

       {INPUTS}

       LON = 0;
       LAT = 1;
       Y   = 2;
       M   = 3;
       D   = 4;

       {OUTPUTS}
       SU = 0;
       SD = 1;
       HRS = 2;


       {USER}
       DLLIndex = 100;       // DLL No. set by ProfiLab

Type TDLLParams = array[0..100] of extended;   // Type of ProfiLab DLL parameters
     PDLLParams = ^TDLLParams;                 // Pointer to ProfiLab DLL parameters

     // Ansi
     TStringParams = array[0..100] of PAnsiChar; // Additional string parameters for CalculateEx
     PStringParams = ^TStringParams;           // Pointer to string parameters

function NumInputs: Byte;
begin
  result:=Inputs; //Define number of component input pins
end;

function NumOutputs: Byte;
begin
  result:=Outputs; //Define number of component output pins
end;

Function InputName(Channel: Byte): ShortString; // Return name for each component input pin
begin
   // string inputs must be named with leading '$' character
   case Channel of
   LON:  result:='LON';
   LAT:  result:='LAT';
   Y:  result:='Y';
   M:  result:='M';
   D:  result:='D';
   end;
end;

Function OutputName(Channel: Byte): ShortString; // Return name for each component output pin
begin
   // string outputs must be named with leading '$' character!
   case Channel of
   SU: result:='$SU';
   SD: result:='$SD';
   HRS: result:='$HRS';
   end;
end;

// New CalculateEx method now allows string parameters...
Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams); //called regularly from ProfiLab
var aAnsiString: AnsiString;
    Longitude, Latitude: extended;
    Day, Month, Year: extended;
    SunUp, SunDown, SunTime, TheDate: TDateTime;
begin
   try
      // Get the inputs
      Longitude:=PInput^[LON];               // input numeric value
      if Longitude>180 then Longitude:=180;    // upper limit
      if Longitude<-180 then Longitude:=-180;  // lower limit

      Latitude:=PInput^[LAT];               // input numeric value
      if Latitude>90 then Latitude:=90;    // upper limit
      if Latitude<-90 then Latitude:=-90;  // lower limit

      Day:=PInput^[D];               // input numeric value
      if Day>31 then Day:=31;    // upper limit
      if Day<1 then Day:=1;  // lower limit

      Month:=PInput^[M];               // input numeric value
      if Month>12 then Month:=12;    // upper limit
      if Month<1 then Month:=1;  // lower limit

      Year:=PInput^[Y];               // input numeric value
      if Year>3000 then Year:=3000;    // upper limit
      if Year<1900 then Year:=1900;  // lower limit

      TheDate:=EncodeDate(round(Year),round(Month),round(Day)); // The day we look for


      // Hope it works - dont blame me if not and dont ask me for details. Found it on the web.
      // Fine for my light control - maybe not for science!
      sunshine(Latitude, Longitude, TheDate, SunUp, SunDown, SunTime);


      // Set the outouts...
      aAnsiString:=TimeToStr(TTimeZone.Local.ToLocalTime(SunUp)); // word to hex
      strPCopy(PStrings[SU], aAnsiString);      // return $hex string result

      aAnsiString:=TimeToStr(TTimeZone.Local.ToLocalTime(SunDown)); // word to hex
      strPCopy(PStrings[SD], aAnsiString);      // return $hex string result

      aAnsiString:=TimeToStr(SunTime); // word to hex
      strPCopy(PStrings[HRS], aAnsiString);      // return $hex string result
   except
      aAnsiString:='Error'; // word to hex
      strPCopy(PStrings[SU], aAnsiString);      // return $hex string result
      strPCopy(PStrings[SD], aAnsiString);      // return $hex string result
      strPCopy(PStrings[HRS], aAnsiString);      // return $hex string result
   end;

end;

//export methods for ProfiLab
exports NumInputs,
        NumOutputs,
        CalculateEx,
        InputName,
        OutputName;
begin
end.
