unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls,
  ZylCustomGPSReceiver, ZylUdpGPSReceiver;

type
  TfrmMain = class(TForm)
    btnStart: TButton;
    btnStop: TButton;
    memRaw: TMemo;
    GroupBox1: TGroupBox;
    efLatDeg: TEdit;
    Label1: TLabel;
    efLatMin: TEdit;
    Label2: TLabel;
    efLatSec: TEdit;
    Label3: TLabel;
    efLatDir: TEdit;
    Label4: TLabel;
    GroupBox2: TGroupBox;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    efLongDeg: TEdit;
    efLongMin: TEdit;
    efLongSec: TEdit;
    efLongDir: TEdit;
    GroupBox3: TGroupBox;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    efAlt: TEdit;
    efSpeed: TEdit;
    efHeading: TEdit;
    efSatCount: TEdit;
    Label13: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    lblUTCTime: TLabel;
    lblLocalTime: TLabel;
    PaintBox: TPaintBox;
    efPort: TEdit;
    Label14: TLabel;
    cmpZylGPSReceiver: TZylUdpGPSReceiver;
    procedure cmpZylGPSReceiverReceive(Sender: TObject);
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure cmpZylGPSReceiverSpeedChange(Sender: TObject; Value: Extended);
    procedure cmpZylGPSReceiverHeadingChange(Sender: TObject; Value: Extended);
    procedure cmpZylGPSReceiverConnect(Sender: TObject; Port: Integer);
    procedure cmpZylGPSReceiverDisconnect(Sender: TObject; Port: Integer);
    procedure cmpZylGPSReceiverAltitudeChange(Sender: TObject; Value: Extended);
    procedure cmpZylGPSReceiverLatitudeChange(Sender: TObject; Degree,
      Minute: Integer; Second: Extended; Direction: TCardinalPoint);
    procedure cmpZylGPSReceiverLongitudeChange(Sender: TObject; Degree,
      Minute: Integer; Second: Extended; Direction: TCardinalPoint);
    procedure cmpZylGPSReceiver2DPositionChange(Sender: TObject; Latitude,
      Longitude: Extended);
    procedure cmpZylGPSReceiver3DPositionChange(Sender: TObject; Latitude,
      Longitude, Altitude: Extended);
    procedure cmpZylGPSReceiverSatelliteReceive(Sender: TObject;
      Satellite: TSatellite);
    procedure PaintBoxPaint(Sender: TObject);
    procedure cmpZylGPSReceiverSatellitesReceive(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.cmpZylGPSReceiverReceive(Sender: TObject);
//var
//  f: TextFile;
begin
  efLatDeg.Text := IntToStr(cmpZylGPSReceiver.GetLatitudeDegree);
  efLatMin.Text := IntToStr(cmpZylGPSReceiver.GetLatitudeMinute);
  efLatSec.Text := FloatToStr(cmpZylGPSReceiver.GetLatitudeSecond);
  if cmpZylGPSReceiver.GetLatitudeDirection = cpNorth then
    efLatDir.Text := 'North'
  else
    efLatDir.Text := 'South';

  efLongDeg.Text := IntToStr(cmpZylGPSReceiver.GetLongitudeDegree);
  efLongMin.Text := IntToStr(cmpZylGPSReceiver.GetLongitudeMinute);
  efLongSec.Text := FloatToStr(cmpZylGPSReceiver.GetLongitudeSecond);
  if cmpZylGPSReceiver.GetLongitudeDirection = cpEast then
    efLongDir.Text := 'East'
  else
    efLongDir.Text := 'West';

  efAlt.Text := FloatToStr(cmpZylGPSReceiver.GetAltitude);
  efSpeed.Text := FloatToStr(cmpZylGPSReceiver.GetSpeed_KMH);
  efHeading.Text := FloatToStr(cmpZylGPSReceiver.GetHeading);
  efSatCount.Text := IntToStr(cmpZylGPSReceiver.GetSatelliteCount);

  lblUTCTime.Caption := DateTimeToStr(cmpZylGPSReceiver.GetUTCDateTime);
  lblLocalTime.Caption := DateTimeToStr(cmpZylGPSReceiver.GetLocalDateTime);

  try
    memRaw.Lines.Add(cmpZylGPSReceiver.GetRawData);
    memRaw.Lines.Add('Fix = ' + IntToStr(cmpZylGPSReceiver.IsFix));
    //AssignFile(f, 'c:\gpsout.txt');
    //Append(f);
    //Write(f, ZylGPSReceiver.GetRawData);
    //CloseFile(f);
    memRaw.Lines.Add('---------------------------------------------------------')
  except
    memRaw.Lines.Clear;
  end;
end;

procedure TfrmMain.btnStartClick(Sender: TObject);
begin
  try
    cmpZylGPSReceiver.Port := StrToInt(efPort.Text);
    cmpZylGPSReceiver.Open;
  except
    MessageDlg('Invalid port.', mtError, [mbOK], 0);
  end;
end;

procedure TfrmMain.btnStopClick(Sender: TObject);
begin
  cmpZylGPSReceiver.Close;
end;

procedure TfrmMain.cmpZylGPSReceiverSpeedChange(Sender: TObject; Value: Extended);
begin
  memRaw.Lines.Add('Speed Changed:' + FloatToStr(Value) + ' KM/H');
end;

procedure TfrmMain.cmpZylGPSReceiverHeadingChange(Sender: TObject;
  Value: Extended);
begin
  memRaw.Lines.Add('Heading Changed:' + FloatToStr(Value) + ' Degrees');
end;

procedure TfrmMain.cmpZylGPSReceiverConnect(Sender: TObject; Port: Integer);
begin
  memRaw.Lines.Add('Connected to:' + IntToStr(cmpZylGPSReceiver.Port));
end;

procedure TfrmMain.cmpZylGPSReceiverDisconnect(Sender: TObject; Port: Integer);
begin
  memRaw.Lines.Add('Disconnected from:' + IntToStr(cmpZylGPSReceiver.Port));
end;

procedure TfrmMain.cmpZylGPSReceiverAltitudeChange(Sender: TObject;
  Value: Extended);
begin
  memRaw.Lines.Add('Altitude Changed:' + FloatToStr(Value) + ' M');
end;

procedure TfrmMain.cmpZylGPSReceiverLatitudeChange(Sender: TObject; Degree,
  Minute: Integer; Second: Extended; Direction: TCardinalPoint);
begin
  memRaw.Lines.Add('Latitude Changed: ' + FloatToStr(cmpZylGPSReceiver.DMSToDecimalDegrees(Degree, Minute, Second, Direction)));
end;

procedure TfrmMain.cmpZylGPSReceiverLongitudeChange(Sender: TObject; Degree,
  Minute: Integer; Second: Extended; Direction: TCardinalPoint);
begin
  memRaw.Lines.Add('Longitude Changed: ' + FloatToStr(cmpZylGPSReceiver.DMSToDecimalDegrees(Degree, Minute, Second, Direction)));
end;

procedure TfrmMain.cmpZylGPSReceiver2DPositionChange(Sender: TObject;
  Latitude, Longitude: Extended);
begin
  memRaw.Lines.Add('2D Position Changed. Distance to New York City = ' + FloatToStr(cmpZylGPSReceiver.Distance_Km(Latitude, Longitude, 40.77, 73.98)) + ' KM');
end;

procedure TfrmMain.cmpZylGPSReceiver3DPositionChange(Sender: TObject;
  Latitude, Longitude, Altitude: Extended);
begin
  memRaw.Lines.Add('3D Position Changed.');
end;

procedure TfrmMain.cmpZylGPSReceiverSatelliteReceive(Sender: TObject;
  Satellite: TSatellite);
var
  str: String;
begin
  str := 'Satellite Received' + ' Code=' + IntToStr(Satellite.PseudoRandomCode);
  str := str + ' Elevation=' + IntToStr(Satellite.Elevation);
  str := str + ' Azimuth=' + IntToStr(Satellite.Azimuth);
  str := str + ' Signal=' + IntToStr(Satellite.SignalToNoiseRatio);
  memRaw.Lines.Add(str);
end;

procedure TfrmMain.PaintBoxPaint(Sender: TObject);
var
  origX, origY: Word;
  circleCount: Word;
  i: Integer;
  p: TPoint;
  x, y: Word;
  Azim, Elev: Word;
  objSat: TSatellite;
  lst: TList;
begin
  origX := PaintBox.Width div 2;
  origY := PaintBox.Height div 2;
  circleCount := 6;
  PaintBox.Canvas.Brush.Color := clBlack;
  PaintBox.Canvas.Pen.Color := clBtnFace;
  PaintBox.Canvas.Pen.Width := 1;
  for i := 1 to circleCount do
  begin
    PaintBox.Canvas.Ellipse((i-1)*PaintBox.Width div (2*CircleCount), (i-1)*PaintBox.Height div (2*CircleCount),
      (2*CircleCount - i + 1)*PaintBox.Width div (2*CircleCount), (2*CircleCount - i + 1)*PaintBox.Height div (2*CircleCount));
  end;

  p.X := PaintBox.Width div 2;
  p.Y := 0;
  PaintBox.Canvas.PenPos := p;
  PaintBox.Canvas.LineTo(PaintBox.Width div 2, PaintBox.Height);

  p.X := PaintBox.Width div 2 + Round((sin(pi/6)/cos(pi/6)) * PaintBox.Height / 2);
  p.Y := 0;
  PaintBox.Canvas.PenPos := p;
  PaintBox.Canvas.LineTo(PaintBox.Width div 2 - Round((sin(pi/6)/cos(pi/6)) * PaintBox.Height / 2), PaintBox.Height);

  p.X := PaintBox.Width div 2 + Round((sin(pi/3)/cos(pi/3)) * PaintBox.Height / 2);
  p.Y := 0;
  PaintBox.Canvas.PenPos := p;
  PaintBox.Canvas.LineTo(PaintBox.Width div 2 - Round((sin(pi/3)/cos(pi/3)) * PaintBox.Height / 2), PaintBox.Height);

  p.X := PaintBox.Width div 2 + Round((sin(2*pi/3)/cos(2*pi/3)) * PaintBox.Height / 2);
  p.Y := 0;
  PaintBox.Canvas.PenPos := p;
  PaintBox.Canvas.LineTo(PaintBox.Width div 2 - Round((sin(2*pi/3)/cos(2*pi/3)) * PaintBox.Height / 2), PaintBox.Height);

  
  p.X := PaintBox.Width div 2 + Round((sin(5*pi/6)/cos(5*pi/6)) * PaintBox.Height / 2);
  p.Y := 0;
  PaintBox.Canvas.PenPos := p;
  PaintBox.Canvas.LineTo(PaintBox.Width div 2 - Round((sin(5*pi/6)/cos(5*pi/6)) * PaintBox.Height / 2), PaintBox.Height);

  p.X := PaintBox.Width;
  p.Y := PaintBox.Height div 2;
  PaintBox.Canvas.PenPos := p;
  PaintBox.Canvas.LineTo(0, PaintBox.Height div 2);

  //draw origin
  PaintBox.Canvas.Ellipse(origX-3, origY-3, origX+3, origY+3);

  lst := cmpZylGPSReceiver.GetSatellites;
  for i := 0 to lst.Count - 1 do
  begin
    objSat := lst[i];
    x := Round((PaintBox.Width/2 - PaintBox.Width*objSat.Elevation/180) * sin(PI - objSat.Azimuth*PI/180)) + PaintBox.Width div 2;
    y := Round((PaintBox.Width/2 - PaintBox.Width*objSat.Elevation/180) * cos(PI - objSat.Azimuth*PI/180)) + PaintBox.Height div 2;
    if objSat.SignalToNoiseRatio > 0 then
      PaintBox.Canvas.Brush.Color := clGreen
    else
      PaintBox.Canvas.Brush.Color := clRed;
    PaintBox.Canvas.Ellipse(X-12, Y-12, X+12, Y+12);
    if objSat.PseudoRandomCode <= 9 then
      PaintBox.Canvas.TextOut(X-6, Y-6, IntToStr(objSat.PseudoRandomCode))
    else
      PaintBox.Canvas.TextOut(X-8, Y-8, IntToStr(objSat.PseudoRandomCode))    
  end;
end;

procedure TfrmMain.cmpZylGPSReceiverSatellitesReceive(Sender: TObject);
begin
  PaintBox.Repaint;
end;

end.
