unit spr_spr;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Mask, Spin,
  Spr_t, SPR_DELPH;

type
  TOknoGlowne = class(TForm)
    Grupa: TGroupBox;
    EkranMemo: TMemo;
    NazwaDoLiniaAdresuIP: TLabel;
    LiniaAdresuSprawdzarki: TMaskEdit;
    KlawiszStatus: TButton;
    KlawiszTeksty: TButton;
    procedure InicjujProgram(Sender: TObject);
    procedure SprawdzarkiStart;
    procedure CentrowanieNapisu(var Napis : string; DlugoscNapisu : byte);
    procedure CoWyswietlicIDrukowac(AdresIP : string; Barkod : string;
      var TekstNaWyswietlacz : string; var RodzajDzwieku : Longword; var CzasWyswietlania : Longword;
      var TekstDoDrukarki : string);
    procedure SprawdzarkiStop;
    procedure KoniecProgramu(Sender: TObject);
    procedure DajStatus(Sender: TObject);
    procedure WejdzDoTextow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  PojedynczyTowar          = record
                               KodKreskowy : string;
                               NazwaTowaru : string;
                               CenaTowaru  : string;
                             end;
const
  NapisOczekuje            = 'Czekam na kod kreskowy...';
  NazwaPlikuZBaza          = 'TOWARY.TXT';
  NapisBrakPliku           = 'Nie znaleziono pliku ';

var
  OknoGlowne: TOknoGlowne;
  ZainicjowanoBazeTowarowa : boolean;
  LiczbaTowarowWBazie      : integer;
  BazaTowarowa             : array of PojedynczyTowar;

procedure PCharZeStringa(NapisString : string; var NapisPChar : PChar; ZalokowacPamiecDlaPChar : boolean);
procedure StringZPChara(NapisPChar : PChar; var NapisString : string; ZwolnicPamiecDlaPChar : boolean);

implementation

{$R *.DFM}

function NapisZawieraPodnapis(NapisDoSprawdzenia : string;
  NumerPodnapisu : byte; RozdzielnikPodnapisow : char; var PodnapisZNapisu : string) : boolean;

var
  Licznik       : byte;
  WyjscieZPetli : boolean;

begin
  WyjscieZPetli        := true;
  NapisZawieraPodnapis := false;

  if ((NumerPodnapisu = 0) or (NapisDoSprawdzenia = '')) then
    begin
      PodnapisZNapisu      := '';
      NapisZawieraPodnapis := false;
      Exit;
    end;

  for Licznik := 1 to NumerPodnapisu do
    begin
      PodnapisZNapisu := '';
      repeat
        if (NapisDoSprawdzenia[1] <> RozdzielnikPodnapisow) then
          begin
            PodnapisZNapisu := PodnapisZNapisu+NapisDoSprawdzenia[1];
            if (Length(NapisDoSprawdzenia) <> 1) then
              begin
                NapisDoSprawdzenia := Copy(NapisDoSprawdzenia, 2,
                  Length(NapisDoSprawdzenia)-1);
                WyjscieZPetli := false;
              end
            else
              begin
                if (Licznik = NumerPodnapisu) then
                  NapisZawieraPodnapis := true
                else
                  begin
                    PodnapisZNapisu      := '';
                    NapisZawieraPodnapis := false;
                  end;
                Exit;
              end;
          end
        else
          if (Licznik <> NumerPodnapisu) then
            begin
              if (NapisDoSprawdzenia = RozdzielnikPodnapisow) then
                begin
                  PodnapisZNapisu      := '';
                  NapisZawieraPodnapis := false;
                  Exit;
                end
              else
                begin
                  NapisDoSprawdzenia := Copy(NapisDoSprawdzenia, 2,
                    Length(NapisDoSprawdzenia)-1);
                  WyjscieZPetli := true;
                end;
            end
          else
            begin
              NapisZawieraPodnapis := (PodnapisZNapisu <> '');
              Exit;
            end;
      until (WyjscieZPetli);
    end;
end;

{******************************************************************************}

function NapisZawieraDana(NapisDoSprawdzenia : string; NumerDanej : byte;
  var DanaZNapisu : string) : boolean;

begin
  NapisZawieraDana := NapisZawieraPodnapis(NapisDoSprawdzenia, NumerDanej, #9,
    DanaZNapisu);
end;

{******************************************************************************}

procedure TOknoGlowne.InicjujProgram(Sender: TObject);

var
  Plik        : TextFile;
  Licznik     : integer;
  LiniaZPliku : string;
  DanaZPliku  : string;

begin
  if (ZainicjowanoBazeTowarowa) then
    Exit;

  ZainicjowanoBazeTowarowa := true;
  EkranMemo.Clear;

  if (not FileExists(NazwaPlikuZBaza)) then
    begin
      EkranMemo.Lines.Add(NapisBrakPliku+NazwaPlikuZBaza+'...');
      Exit;
    end;

  AssignFile(Plik, NazwaPlikuZBaza);
  Reset(Plik);

  for Licznik := 1 to 3 do
    ReadLn(Plik, LiniaZPliku);

  LiczbaTowarowWBazie := 0;
  while (not Eof(Plik)) do
    begin
      SetLength(BazaTowarowa, LiczbaTowarowWBazie+2);

      ReadLn(Plik, LiniaZPliku);

      if (not NapisZawieraDana(LiniaZPliku, 2, DanaZPliku)) then
        break;
      BazaTowarowa[LiczbaTowarowWBazie+1].NazwaTowaru := DanaZPliku;

      if (not NapisZawieraDana(LiniaZPliku, 9, DanaZPliku)) then
        break;
      while (Length(DanaZPliku) < 3) do
        DanaZPliku := '0'+DanaZPliku;
      BazaTowarowa[LiczbaTowarowWBazie+1].CenaTowaru := Copy(DanaZPliku, 1, Length(DanaZPliku)-2)+
        '.'+Copy(DanaZPliku, Length(DanaZPliku)-1, 2);
      while (Length(BazaTowarowa[LiczbaTowarowWBazie+1].CenaTowaru) < 12) do
        BazaTowarowa[LiczbaTowarowWBazie+1].CenaTowaru := ' '+BazaTowarowa[LiczbaTowarowWBazie+1].CenaTowaru;
      BazaTowarowa[LiczbaTowarowWBazie+1].CenaTowaru := 'CENA:'+BazaTowarowa[LiczbaTowarowWBazie+1].CenaTowaru+' zł';

      if (not NapisZawieraDana(LiniaZPliku, 8, DanaZPliku)) then
        break;
      BazaTowarowa[LiczbaTowarowWBazie+1].KodKreskowy := DanaZPliku;

      Inc(LiczbaTowarowWBazie);
    end;

  CloseFile(Plik);

  EkranMemo.Lines.Add('Program stoi!');

  SprawdzarkiStart;
end;

{******************************************************************************}

procedure StringZPChara(NapisPChar : PChar; var NapisString : string; ZwolnicPamiecDlaPChar : boolean);

var
  Licznik : integer;

begin
  NapisString := '';
  Licznik     := 0;
  while (NapisPChar[Licznik] <> chr($00)) do
    begin
      NapisString := NapisString+NapisPChar[Licznik];
      Inc(Licznik);
    end;

  if (ZwolnicPamiecDlaPChar) then
    FreeMem(NapisPChar);
end;

{******************************************************************************}

procedure PCharZeStringa(NapisString : string; var NapisPChar : PChar; ZalokowacPamiecDlaPChar : boolean);

var
  Licznik : byte;

begin
  if (ZalokowacPamiecDlaPChar) then
    NapisPChar := AllocMem(255);

  for Licznik := 1 to Length(NapisString) do
    NapisPChar[Licznik-1] := NapisString[Licznik];
  NapisPChar[Length(NapisString)] := chr($00);
end;

{******************************************************************************}

procedure TOknoGlowne.CentrowanieNapisu(var Napis : string; DlugoscNapisu : byte);

begin
  while (Length(Napis) < DlugoscNapisu) do
    begin
      Napis := Napis+' ';
      if (Length(Napis) < DlugoscNapisu) then
        Napis := ' '+Napis;
    end;
end;

{******************************************************************************}

procedure TOknoGlowne.CoWyswietlicIDrukowac(AdresIP : string; Barkod : string;
  var TekstNaWyswietlacz : string; var RodzajDzwieku : Longword; var CzasWyswietlania : Longword;
  var TekstDoDrukarki : String);

type
  MozliweTypyBarkodu = (ZnalezionoTowarWBazie,
                        BrakTowaruWBazie,
                        BarkodSerwisowy);

var
  Licznik            : integer;
  LinieNaWyswietlacz : array [1..2] of string;
  LinieDoDrukarki    : array [1..10] of string;
  TypBarkodu         : MozliweTypyBarkodu;

begin
  TypBarkodu := ZnalezionoTowarWBazie;

  for Licznik := 1 to LiczbaTowarowWBazie do
    if (BazaTowarowa[Licznik].KodKreskowy = Barkod) then
      begin
        LinieNaWyswietlacz[1] := BazaTowarowa[Licznik].NazwaTowaru;
        LinieNaWyswietlacz[2] := BazaTowarowa[Licznik].CenaTowaru;
        RodzajDzwieku         := 0;
        CzasWyswietlania      := 3;
        break;
      end;

  if (Licznik > LiczbaTowarowWBazie) then
    begin
      LinieNaWyswietlacz[1] := 'BRAK TOWARU O KODZIE';
      LinieNaWyswietlacz[2] := Barkod;
      RodzajDzwieku         := 2;
      CzasWyswietlania      := 1;
      TypBarkodu            := BrakTowaruWBazie;
    end;

  if (Barkod = '5946798220006') then
    begin
      LinieNaWyswietlacz[1] := 'INFORMACJA SERWISOWA';
      LinieNaWyswietlacz[2] := 'IP = '+AdresIP;
      RodzajDzwieku         := 1;
      CzasWyswietlania      := 0;
      TypBarkodu            := BarkodSerwisowy;
    end;

  TekstNaWyswietlacz := '';
  for Licznik := 1 to 2 do
    begin
      OknoGlowne.CentrowanieNapisu(LinieNaWyswietlacz[Licznik], 20);
      TekstNaWyswietlacz := TekstNaWyswietlacz+LinieNaWyswietlacz[Licznik];
    end;

  for Licznik := 1 to 10 do
    LinieDoDrukarki[Licznik] := '';

  case (TypBarkodu) of
    ZnalezionoTowarWBazie :
      begin
        LinieDoDrukarki[1] := DC2+DC3+LinieNaWyswietlacz[1]+LF;
        LinieDoDrukarki[2] := 'Kod kreskowy: '+Barkod;
        OknoGlowne.CentrowanieNapisu(LinieDoDrukarki[2], 40);
        LinieDoDrukarki[2] := DC1+LinieDoDrukarki[2]+LF;
        LinieDoDrukarki[3] := DC1+LF;
        LinieDoDrukarki[4] := DC2+DC3+LinieNaWyswietlacz[2]+LF;
        LinieDoDrukarki[5] := DC1+LF;
        LinieDoDrukarki[6] := DC1+LF;
        LinieDoDrukarki[7] := DC1+LF;
        LinieDoDrukarki[8] := DC1+LF;
      end;
    BarkodSerwisowy       :
      begin
        LinieDoDrukarki[1] := DC2+DC3+LinieNaWyswietlacz[1]+LF;
        LinieDoDrukarki[4] := DC2+DC3+LinieNaWyswietlacz[2]+LF;
        LinieDoDrukarki[5] := DC1+LF;
        LinieDoDrukarki[6] := DC1+LF;
        LinieDoDrukarki[7] := DC1+LF;
        LinieDoDrukarki[8] := DC1+LF;
      end;
  end;

  TekstDoDrukarki := '';
  for Licznik := 1 to 10 do
    TekstDoDrukarki := TekstDoDrukarki+LinieDoDrukarki[Licznik];
end;

{******************************************************************************}

procedure ObslugaPytanZeSprawdzarek(AdresIP : PChar; Barkod : PChar; TekstNaWyswietlacz : PChar; var RodzajDzwieku : Longword;
  var CzasWyswietlania : Longword; TekstDoDrukowania : PChar); StdCall;

const
  NieAlokowacZwalniacPamieci = false;

var
  StringAdresIP              : string;
  StringBarkod               : string;
  StringTekstNaWyswietlacz   : string;
  StringTekstDoDrukowania    : string;
  NapisPomocniczy            : string;

begin
  StringZPChara(AdresIP           , StringAdresIP           , NieAlokowacZwalniacPamieci);
  StringZPChara(Barkod            , StringBarkod            , NieAlokowacZwalniacPamieci);
  StringZPChara(TekstNaWyswietlacz, StringTekstNaWyswietlacz, NieAlokowacZwalniacPamieci);
  StringZPChara(TekstDoDrukowania , StringTekstDoDrukowania , NieAlokowacZwalniacPamieci);

  OknoGlowne.CoWyswietlicIDrukowac(StringAdresIP, StringBarkod, StringTekstNaWyswietlacz, RodzajDzwieku, CzasWyswietlania,
    StringTekstDoDrukowania);

  OknoGlowne.EkranMemo.Lines.Delete(OknoGlowne.EkranMemo.Lines.Count-1);
  NapisPomocniczy := 'Posłano na wyświetlacz sprawdzarki nr '+StringAdresIP+':';
  OknoGlowne.EkranMemo.Lines.Add(NapisPomocniczy);
  NapisPomocniczy := Copy(StringTekstNaWyswietlacz, 1, 20);
  OknoGlowne.EkranMemo.Lines.Add(NapisPomocniczy);
  NapisPomocniczy := Copy(StringTekstNaWyswietlacz, 21, 20);
  OknoGlowne.EkranMemo.Lines.Add(NapisPomocniczy);

  OknoGlowne.EkranMemo.Lines.Add('');
  OknoGlowne.EkranMemo.Lines.Add(NapisOczekuje);

  OknoGlowne.LiniaAdresuSprawdzarki.Text := AdresIP;

  StringTekstNaWyswietlacz := StringNaLatin2(StringTekstNaWyswietlacz);

  PCharZeStringa(StringAdresIP           , AdresIP           , NieAlokowacZwalniacPamieci);
  PCharZeStringa(StringBarkod            , Barkod            , NieAlokowacZwalniacPamieci);
  PCharZeStringa(StringTekstNaWyswietlacz, TekstNaWyswietlacz, NieAlokowacZwalniacPamieci);
  PCharZeStringa(StringTekstDoDrukowania , TekstDoDrukowania , NieAlokowacZwalniacPamieci);
end;

{******************************************************************************}

procedure ObslugaStatusuZeSprawdzarek(AdresIP : PChar; TypWyswietlacza : Longword; TypDrukarki : Longword; Status : Longword; Wersja : PChar); StdCall;

const
  NieAlokowacZwalniacPamieci = false;

var
  StringAdresIP              : string;
  StringWersja               : string;
  StringTypWyswietlacza      : string;
  StringTypDrukarki          : string;
  StringTakNie               : string;

begin
  StringZPChara(AdresIP, StringAdresIP, NieAlokowacZwalniacPamieci);
  StringZPChara(Wersja , StringWersja , NieAlokowacZwalniacPamieci);

  with (OknoGlowne.EkranMemo) do
    begin
      Lines.Delete(Lines.Count-1);

      Lines.Add('Sprawdzarka nr         : '+StringAdresIP);

      Lines.Add('Wersja firmware        : '+StringWersja);

      Str(TypWyswietlacza, StringTypWyswietlacza);
      Lines.Add('Typ wyswietlacza       : '+StringTypWyswietlacza);

      Str(TypDrukarki, StringTypDrukarki);
      Lines.Add('Typ drukarki           : '+StringTypDrukarki);

      if ((Status and $01) = $01) then
        StringTakNie := 'TAK'
      else
        StringTakNie := 'nie';
      Lines.Add('Brak papieru           : '+StringTakNie);

      if ((Status and $02) = $02) then
        StringTakNie := 'TAK'
      else
        StringTakNie := 'nie';
      Lines.Add('Mało papieru           : '+StringTakNie);

      if ((Status and $04) = $04) then
        StringTakNie := 'TAK'
      else
        StringTakNie := 'nie';
      Lines.Add('Uszkodzona drukarka    : '+StringTakNie);

      if ((Status and $08) = $08) then
        StringTakNie := 'TAK'
      else
        StringTakNie := 'nie';
      Lines.Add('Uszkodzony wyswietlacz : '+StringTakNie);

      if ((Status and $10) = $10) then
        StringTakNie := 'TAK'
      else
        StringTakNie := 'nie';
      Lines.Add('Niskie napięcie        : '+StringTakNie);

      if ((Status and $20) = $20) then
        StringTakNie := 'TAK'
      else
        StringTakNie := 'nie';
      Lines.Add('Pełny pojemnik         : '+StringTakNie);

      Lines.Add('');
      Lines.Add(NapisOczekuje);
    end;

  PCharZeStringa(StringAdresIP, AdresIP, NieAlokowacZwalniacPamieci);
  PCharZeStringa(StringWersja , Wersja , NieAlokowacZwalniacPamieci);
end;

{******************************************************************************}

procedure ObslugaBledowZeSprawdzarek(AdresIP : PChar; TypTransmisji : Longword; NrBledu : Longword; OpisBledu : PChar); StdCall;

const
  NieAlokowacZwalniacPamieci = false;

var
  StringAdresIP              : string;
  StringOpisBledu            : string;
  StringNrBledu              : string;

begin
  StringZPChara(AdresIP  , StringAdresIP  , NieAlokowacZwalniacPamieci);
  StringZPChara(OpisBledu, StringOpisBledu, NieAlokowacZwalniacPamieci);

  with (OknoGlowne.EkranMemo) do
    begin
      Lines.Delete(Lines.Count-1);

      Lines.Add('Sprawdzarka nr : '+StringAdresIP);

      Str(NrBledu, StringNrBledu);
      Lines.Add('Błąd nr : '+StringNrBledu+' ('+StringOpisBledu+')');

      Lines.Add('');
      Lines.Add(NapisOczekuje);
    end;

  PCharZeStringa(StringAdresIP  , AdresIP  , NieAlokowacZwalniacPamieci);
  PCharZeStringa(StringOpisBledu, OpisBledu, NieAlokowacZwalniacPamieci);
end;

{******************************************************************************}

procedure TOknoGlowne.SprawdzarkiStart;

const
  AlokowacZwalniacPamiec = true;

var
  NrBledu                : Longword;
  OpisBledu              : PChar;
  StringOpisBledu        : string;
  StringNrBledu          : string;

begin
  with (EkranMemo) do
    begin
      Lines.Delete(EkranMemo.Lines.Count-1);

      PCharZeStringa('', OpisBledu, AlokowacZwalniacPamiec);
      if (UruchomionoObslugeSprawdzarek(NrBledu, OpisBledu, ObslugaPytanZeSprawdzarek, ObslugaStatusuZeSprawdzarek, ObslugaBledowZeSprawdzarek)) then
        Lines.Add(NapisOczekuje)
      else
        begin
          Lines.Add('Uruchamianie obsługi sprawdzarek:');

          Str(NrBledu, StringNrBledu);
          Lines.Add('Błąd nr : '+StringNrBledu+' ('+OpisBledu+')');
        end;
      StringZPChara(OpisBledu, StringOpisBledu, AlokowacZwalniacPamiec);
    end;
end;

{******************************************************************************}


procedure TOknoGlowne.KoniecProgramu(Sender: TObject);
begin
  SprawdzarkiStop;
end;

{******************************************************************************}

procedure TOknoGlowne.SprawdzarkiStop;

begin
  ZatrzymanieObslugiSprawdzarek;

  with (OknoGlowne.EkranMemo) do
    begin
      Lines.Delete(Lines.Count-1);
      Lines.Add('Zatrzymano obsługę sprawdzarek...');
    end;
end;

{******************************************************************************}

procedure TOknoGlowne.DajStatus(Sender: TObject);

const
  AlokowacZwalniacPamiec = true;

var
  PCharAdresIP           : PChar;
  NapisPomocniczy        : string;

begin
  with (EkranMemo) do
    begin
      Lines.Delete(EkranMemo.Lines.Count-1);
      Lines.Add('Czekam na status ze sprawdzarki nr '+LiniaAdresuSprawdzarki.Text+'...');
    end;

  PCharZeStringa(LiniaAdresuSprawdzarki.Text, PCharAdresIP, AlokowacZwalniacPamiec);
  OdczytajStatus(PCharAdresIP);
  StringZPChara(PCharAdresIP, NapisPomocniczy, AlokowacZwalniacPamiec);
end;

{******************************************************************************}

procedure TOknoGlowne.WejdzDoTextow(Sender: TObject);
begin
   OknoTextow.Show;
end;

end.
