GitHub
Tests: 12 • Commercial: 2 • Pet projects: 4 • Legacy: 4
Total: 22

.NET Framework

Test
2021

Project Request

ASP.NET MVC • C# • SQL Server
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2020

ProjectC

ASP.NET MVC • C# • JSON • jQuery
JSON data processing.
Test
2020

Vehicle Maintenance

ASP.NET MVC • VB.NET • JSON
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2019

Movie Navigator

ASP.NET MVC • VB.NET
Request information about movie from IMDB.
Test
2018

Customers Exchange

ASP.NET MVC • C# • SQL Server
Automated teller machine emulation.
Test
2016

ATM

ASP.NET MVC • C#
Automated teller machine emulation.

.NET Core

Pet project
2022

Mail Daemon

.NET 8 • Console • JSON
Utility to send mails with customizable settings.

Custom

Code
2024

Buns of code

.NET Framework • C# • JavaScript
Code snippets from my projects, ready to use; tiny tests; code examples.

PHP

Test
2024

Mediabox

PHP 8 • Laravel 11 • Vue.js • Composer • SQLite
Test project for media files management.
Test
2020

Loan Castle

PHP • MariaDB
Jums jāizstrādā kāda lielāk projekta prototips. Izstrādājot prototipu, paturiet prātā, ka projektam attīstoties, šo prototipu varētu vajadzēt pilnveidot.
Test
2020

Content Management

PHP • MySQL • AJAX
Создать простой сайт, где будет страница с формой для авторизации и страница для авторизованного пользователя.
Test
2019

Laravel

PHP • Laravel • Vue.js • Composer • SQLite
Izveidot aplikāciju, kura ik pēc noteikta intervāla (60 sekundes) veic ierakstu datubāzē izmantojot Laravel freimworka iebūvēto funkcionalitāti.
Test
2019

Phone Check

PHP • JavaScript • JSON • Docker
Implement application to detect country by phone number.

Frontend

Test
2021

Forex Wall

npm • React
For this exercise, what we need is a simple live wall for tracking currencies.

Business projects

Commercial
2008

Certification Center

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Dapper • JavaScript • jQuery • Git
Transport registration and certification services in Latvia, Customer Relationship Management.
Commercial
2000

Amerikas Auto

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Entity Framework • JavaScript • jQuery • Git
Car service and spare parts for all USA and European car models, Customer Relationship Management.

Pet projects

Pet project
2023

Geolocation Assistant

.NET 8 • ASP.NET Core • C# • Web API • JSON • Git
Website for determining geolocation by IP or geotagged photo.
Pet project
2008

Web Dynamics

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
Software development blog. Articles, books, videos, content management.
Pet project
2000

Blackball

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • XML • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
My entertainment portal created from scratch.

Good old times

Legacy
2000

DOS Clock

Turbo Pascal • Assembler
Digital clock.
Legacy
2000

BrainOut

Turbo Pascal • Assembler
Tank battle game.
Legacy
1999

Airport Administrator

Turbo Pascal
Курсовая работа в институте.
Legacy
1998

Atomizer

Turbo Pascal • Assembler
Atomizer, aka «Studio2D». Graphic raster editor. AGI is my own «Atomizer Generated Image» file format.

Airport Administrator

1999 Legacy

Курсовая работа в институте.

Turbo Pascal
Information
Source code
Root / AIRLIB.PAS
Unit AirLib; Interface Uses Crt, Graph, Dos, Globals, General, Menus; Type AirportType = record Code : LongInt; FullName : String; Situation : String; end; EditType = record BoxAlt : Word; BoxLen : Word; BoxData : String; end; OperationType = ( AddOp, EditOp ); Const MENU_ITEM_LIST_MainMenu : array [ 0..3 ] of String=( 'File', 'Edit', 'Find', 'Help' ); MENU_ITEM_LIST_File : array [ 0..2 ] of String=( '...', 'Clear', 'Exit' ); MENU_ITEM_LIST_Edit : array [ 0..3 ] of String=( '...', 'Add record...', 'Edit record...', 'Remove record...' ); MENU_ITEM_LIST_Help : array [ 0..2 ] of String=( '...', 'Help', 'About...' ); MENU_MAXITEMS_MainMenu = 4; MENU_MAXITEMS_File = 3; MENU_MAXITEMS_Edit = 4; MENU_MAXITEMS_Help = 3; DATAFILENAME = 'data.adb'; OperWinX = 139; OperWinY = 60; Var Airport : array [ 1..5000 ] of ^AirportType; TotalRecords : Integer; CurRec : Integer; MaxRecsInWin : Byte; TabOfs : Integer; RedrawFlag : Boolean; Edit : array [ 1..3 ] of EditType; EditPointer : ShortInt; OldEditPointer : ShortInt; Procedure About; Procedure ClearADB; Procedure EditRecList( Operation : OperationType ); Procedure FindRecord; Procedure Help; Procedure Operations; Procedure OutputData; Procedure Quit; Procedure ReadData; Procedure RefreshDatabase; Procedure SortDatabase; {----------------------------------------------------------------------------} Implementation Procedure About; Const AbWinY = 180; begin CreateWindow( GetMaxX div 2 - 150, AbWinY, GetMaxX div 2 - 105, 221, 'About Airport Administrator' ); SetColor( 0 ); SetTextStyle( 1, 0, 1 ); OutTextXY( GetMaxX div 2 - 130, AbWinY + 35, 'Airport Administrator v.1.0' ); SetTextStyle( 2, 0, 0 ); OutTextXY( GetMaxX div 2 - 120, AbWinY + 80, 'Created by Sergei Drozdov' ); OutTextXY( GetMaxX div 2 - 120, AbWinY + 95, 'Student of RAU, group 4802' ); OutTextXY( GetMaxX div 2 - 120, AbWinY + 110, 'Pascal programming course work' ); OutTextXY( GetMaxX div 2 - 120, AbWinY + 125, 'This program is system of database control' ); OutTextXY( GetMaxX div 2 - 120, AbWinY + 150, '(R) All Rights Reserved' ); OutTextXY( GetMaxX div 2 - 120, AbWinY + 165, 'Copyright (C) 1999-2001' ); PutDetatcher( GetMaxX div 2 - 145, AbWinY + 190, 283 ); SetColor( 0 ); OutTextXY( GetMaxX div 2 - 140, AbWinY + 200, 'Esc - Close' ); repeat if KeyPressed then begin Key := ReadKey; if Key = ESC then begin BarDeluxe( 5, 55, GetMaxX - 8, GetMaxY - 60, 1, 23 ); Exit; end; end; until False; end; { of 'About' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure ClearADB; begin if TotalRecords = 0 then begin MessageBox( 'Database is empty' ); Exit; end else begin if DialogBox( 'All database will be lost. Continue?', 1 ) = 0 then begin TotalRecords := 0; Assign( F, DATAFILENAME ); Rewrite( F, 1 ); BlockWrite( F, TotalRecords , 5 ); Close( F ); MessageBox( 'Database is clear' ); end; end; end; { of 'ClearADB' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure EditRecList; Label LoopAddWithINSERTkey; Const AddRecWinX = 298; AddRecWinY = 180; AddRecWinLen = 205; AddRecWinHeight = 256; Var OpName : String; RecDuplicateFlag : Boolean; UndoEditCode : LongInt; UndoEditFullName : String; UndoEditSituation : String; EMScreenSize : LongInt; EMP : Pointer; begin Edit[ 1 ].BoxAlt := 45; Edit[ 2 ].BoxAlt := 105; Edit[ 3 ].BoxAlt := 165; Edit[ 1 ].BoxLen := 34; { Airport code field length } Edit[ 2 ].BoxLen := 142; { Airport fullname field length } Edit[ 3 ].BoxLen := 142; { Airport situation field length } EMScreenSize := ImageSize( AddRecWinX, AddRecWinY, AddRecWinX + AddRecWinLen, AddRecWinY + AddRecWinHeight ); GetMem( EMP, EMScreenSize ); { Allocate memory on heap } GetImage( AddRecWinX, AddRecWinY, AddRecWinX + AddRecWinLen, AddRecWinY + AddRecWinHeight, EMP^ ); LoopAddWithINSERTkey: EditPointer := 1; RecDuplicateFlag := False; if Operation = AddOp then { Add record } begin OpName := 'Add'; Inc( TotalRecords ); { Increase records counter } if TotalRecords = 5001 then begin MessageBox( 'Unable to add record. Too many records' ); TotalRecords := 5000; Exit; end; New( Airport[ TotalRecords ] ); Airport[ TotalRecords ]^.Code := 0; Airport[ TotalRecords ]^.FullName := ''; Airport[ TotalRecords ]^.Situation := ''; Edit[ 1 ].BoxData := ''; Edit[ 2 ].BoxData := ''; Edit[ 3 ].BoxData := ''; CreateWindow( AddRecWinX, AddRecWinY, AddRecWinLen, AddRecWinHeight, OpName + ' - ' + IntToStr( TotalRecords ) + ' record' ); end; if Operation = EditOp then { Edit record } if TotalRecords = 0 then { Database is empty } begin FreeMem( EMP, EMScreenSize ); MessageBox( 'Database is empty' ); Exit; end else { TotalRecords > 0 } begin OpName := 'Edit Record'; UndoEditCode := Airport[ CurRec ]^.Code; { If canceled } UndoEditFullName := Airport[ CurRec ]^.FullName; { If canceled } UndoEditSituation := Airport[ CurRec ]^.Situation; { If canceled } Edit[ 1 ].BoxData := IntToStr( Airport[ CurRec ]^.Code ); Edit[ 2 ].BoxData := Airport[ CurRec ]^.FullName; Edit[ 3 ].BoxData := Airport[ CurRec ]^.Situation; CreateWindow( AddRecWinX, AddRecWinY, AddRecWinLen, AddRecWinHeight, OpName ); end; Area( AddRecWinX + 10, AddRecWinY + 30, 90, 45, 'Airport code' ); DrawInputDataBox( AddRecWinX + 22, AddRecWinY + Edit[ 1 ].BoxAlt, 9 ); Area( AddRecWinX + 10, AddRecWinY + 90, Edit[ 2 ].BoxLen + 43, 45, 'Airport full name' ); DrawInputDataBox( AddRecWinX + 22, AddRecWinY + Edit[ 2 ].BoxAlt, COLOR_2 ); Area( AddRecWinX + 10, AddRecWinY + 150, Edit[ 3 ].BoxLen + 43, 45, 'Airport situation' ); DrawInputDataBox( AddRecWinX + 22, AddRecWinY + Edit[ 3 ].BoxAlt, COLOR_2 ); PutDetatcher( AddRecWinX + 10, AddRecWinY + 205, AddRecWinLen - 20 ); SetColor( 0 ); SetTextStyle( 2, 0, 0 ); OutTextXY( AddRecWinX + 10, AddRecWinY + 213, 'Tab-Forward Shift+Tab-Backward' ); OutTextXY( AddRecWinX + 10, AddRecWinY + 225, 'ESC-Close Insert-Accept' ); OutTextXY( AddRecWinX + 10, AddRecWinY + 237, 'Enter-Input data' ); BarDeluxe( AddRecWinX + 21, AddRecWinY + Edit[ 1 ].BoxAlt + 1, Edit[ 1 ].BoxLen + 21, 14, 1, COLOR_4 ); if Operation = EditOp then { Edit record } begin SetColor( 15 ); OutTextXY( AddRecWinX + 22, AddRecWinY + Edit[ 1 ].BoxAlt + 2, IntToStr( Airport[ CurRec ]^.Code ) ); SetColor( 0 ); OutTextXY( AddRecWinX + 22, AddRecWinY + Edit[ 2 ].BoxAlt + 2, Edit[ 2 ].BoxData ); OutTextXY( AddRecWinX + 22, AddRecWinY + Edit[ 3 ].BoxAlt + 2, Edit[ 3 ].BoxData ); end; repeat if KeyPressed then begin Key := ReadKey; if Key = ESC then { Close } begin if Operation = AddOp then { Close 'Add record' } begin Dispose(Airport[ TotalRecords ] ); Dec( TotalRecords ); SortDatabase; end; if Operation = EditOp then begin { Cancel 'Edit record' } Airport[ CurRec ]^.Code := UndoEditCode; Airport[ CurRec ]^.FullName := UndoEditFullName; Airport[ CurRec ]^.Situation := UndoEditSituation; end; PutImage( AddRecWinX, AddRecWinY, EMP^, NormalPut ); FreeMem( EMP, EMScreenSize ); RedrawFlag := True; OutputData; Exit; end; OldEditPointer := EditPointer; if Key = TAB then Inc( EditPointer ); { Forward } if Key = ENTER then { Add record } begin case EditPointer of 1 : { Airport code } begin if Operation = AddOp then begin Airport[ TotalRecords ]^.Code := InputNumericData( AddRecWinX + 22, AddRecWinY + Edit[ EditPointer ].BoxAlt, 9, Airport[ TotalRecords ]^.Code ); Edit[ EditPointer ].BoxData := IntToStr( Airport[ TotalRecords ]^.Code ); end; if Operation = EditOp then begin Airport[ CurRec ]^.Code := InputNumericData( AddRecWinX + 22, AddRecWinY + Edit[ EditPointer ].BoxAlt, 9, Airport[ CurRec ]^.Code ); Edit[ EditPointer ].BoxData := IntToStr( Airport[ CurRec ]^.Code ); end; OldEditPointer := EditPointer; Inc( EditPointer ); end; 2 : { Airport fullname } begin if Operation = AddOp then begin Airport[ TotalRecords ]^.FullName := InputStringData( AddRecWinX + 22, AddRecWinY + Edit[ EditPointer ].BoxAlt, 27, Airport[ TotalRecords ]^.FullName ); Edit[ EditPointer ].BoxData := Airport[ TotalRecords ]^.FullName; end; if Operation = EditOp then begin Airport[ CurRec ]^.FullName := InputStringData( AddRecWinX + 22, AddRecWinY + Edit[ EditPointer ].BoxAlt, 27, Airport[ CurRec ]^.FullName ); Edit[ EditPointer ].BoxData := Airport[ CurRec ]^.FullName; end; OldEditPointer := EditPointer; Inc( EditPointer ); end; 3 : { Airport situation } begin if Operation = AddOp then begin Airport[ TotalRecords ]^.Situation := InputStringData( AddRecWinX + 22, AddRecWinY + Edit[ EditPointer ].BoxAlt, 27, Airport[ TotalRecords ]^.Situation ); Edit[ EditPointer ].BoxData := Airport[ TotalRecords ]^.Situation; end; if Operation = EditOp then begin Airport[ CurRec ]^.Situation := InputStringData( AddRecWinX + 22, AddRecWinY + Edit[ EditPointer ].BoxAlt, 27, Airport[ CurRec ]^.Situation ); Edit[ EditPointer ].BoxData := Airport[ CurRec ]^.Situation; end; OldEditPointer := EditPointer; Inc( EditPointer ); end; end; { case Edit.Pointer } end; if Key = #0 then begin Key := ReadKey; case Key of SHIFT_TAB_ext : Dec( EditPointer ); { Backward } INSERT_ext : { Accept record } begin for Counter := 1 to TotalRecords - 1 do begin if ( Airport[ TotalRecords ]^.Code = Airport[ Counter ]^.Code ) and ( Airport[ TotalRecords ]^.FullName = Airport[ Counter ]^.FullName ) and ( Airport[ TotalRecords ]^.Situation = Airport[ Counter ]^.Situation ) then RecDuplicateFlag := True; end; if ( Airport[ TotalRecords ]^.Code = 0 ) or ( Airport[ TotalRecords ]^.FullName = '' ) or ( Airport[ TotalRecords ]^.Situation = '' ) then MessageBox( 'Each field must content data' ) else if RecDuplicateFlag then begin MessageBox( 'Record already existed' ); RecDuplicateFlag := False; end else begin { All fields contents data } Panel( OperWinX + 6, OperWinY + 467, 122, 18, COLOR_3, COLOR_2, COLOR_1 ); SetColor( 0 ); OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); if Operation = AddOp then { Add record } begin Assign( F, DATAFILENAME ); {$I-} Reset( F, 1 ); {$I+} BlockWrite( F, TotalRecords, 5 ); Seek( F, FileSize( F ) ); BlockWrite( F, Airport[ TotalRecords ]^.Code, 9 ); BlockWrite( F, Airport[ TotalRecords ]^.FullName, 28 ); BlockWrite( F, Airport[ TotalRecords ]^.Situation, 28 ); Close(F); RedrawFlag := True; OutputData; goto LoopAddWithINSERTkey; end; if Operation = EditOp then begin { Accept edition and exit } PutImage( AddRecWinX, AddRecWinY, EMP^, NormalPut ); FreeMem( EMP, EMScreenSize ); SortDatabase; RedrawFlag := True; OutputData; Exit; end; end; end; { Insert } end; {case Key} end; if EditPointer = 0 then EditPointer := 3; if EditPointer = 4 then EditPointer := 1; BarDeluxe( AddRecWinX + 21, AddRecWinY + Edit[ OldEditPointer ].BoxAlt + 1, Edit[ OldEditPointer ].BoxLen + 21, 14, 1, COLOR_5 ); SetColor( 0 ); OutTextXY( AddRecWinX + 22, AddRecWinY + Edit[ OldEditPointer ].BoxAlt + 2, Edit[ OldEditPointer ].BoxData ); BarDeluxe( AddRecWinX + 21, AddRecWinY + Edit[ EditPointer ].BoxAlt + 1, Edit[ EditPointer ].BoxLen + 21, 14, 1, COLOR_4 ); SetColor( 15 ); OutTextXY( AddRecWinX + 22, AddRecWinY + Edit[ EditPointer ].BoxAlt + 2, Edit[ EditPointer ].BoxData ); end; { KeyPressed} until False; end; { of 'EditRecList'} {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure FindRecord; Var FindNum : LongInt; FindFlag : Boolean; FNumCount : Integer; FindBuffer : array [ 1..500 ] of LongInt; SaveTR : Integer; Procedure OutputFoundRecords; begin MaxRecsInWin := 28; if MaxRecsInWin > FNumCount then MaxRecsInWin := FNumCount; for Counter := 1 to MaxRecsInWin do begin if RedrawFlag then begin { Clean fields } BarDeluxe( OperWinX + 21, OperWinY + 48, 58, 392, 1, COLOR_5 ); BarDeluxe( OperWinX + 123, OperWinY + 48, 166, 392, 1, COLOR_5 ); BarDeluxe( OperWinX + 334, OperWinY + 48, 166, 392, 1, COLOR_5 ); end; if ( TabOfs + Counter - 1 ) <> CurRec then begin BarDeluxe( OperWinX + 21, OperWinY + 34 + Counter * 14, 58, 14, 1, COLOR_5 ); BarDeluxe( OperWinX + 123, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_5 ); BarDeluxe( OperWinX + 334, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_5 ); SetColor( 0 ); OutTextXY( OperWinX + 24, OperWinY + 34 + Counter * 14, IntToStr( Airport[ TabOfs + FindBuffer[ Counter ] - 1 ]^.Code ) ); OutTextXY( OperWinX + 126, OperWinY + 34 + Counter * 14, Airport[ TabOfs + FindBuffer[ Counter ] - 1 ]^.FullName ); OutTextXY( OperWinX + 337, OperWinY + 34 + Counter * 14, Airport[ TabOfs + FindBuffer[ Counter ] - 1 ]^.Situation ); RedrawFlag := False; end else begin BarDeluxe( OperWinX + 21, OperWinY + 34 + Counter * 14, 58, 14, 1, COLOR_4 ); BarDeluxe( OperWinX + 123, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_4 ); BarDeluxe( OperWinX + 334, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_4 ); SetColor( 15 ); OutTextXY( OperWinX + 24, OperWinY + 34 + Counter * 14, IntTOStr( Airport[ TabOfs + FindBuffer[ Counter ] - 1 ]^.Code ) ); OutTextXY( OperWinX + 126, OperWinY + 34 + Counter * 14, Airport[ TabOfs + FindBuffer[ Counter ] - 1 ]^. FullName ); OutTextXY( OperWinX + 337, OperWinY + 34 + Counter * 14, Airport[ TabOfs + FindBuffer[ Counter ] - 1 ]^. Situation ); RedrawFlag := False; end; end; end; { of Procedure OutputFoundRecords } begin FindFlag := False; FNumCount := 0; if TotalRecords = 0 then begin MessageBox( 'Database is empty' ); Exit; end else begin { Database isn't empty } CreateWindow( 316, 200, 168, 110, 'Find Record' ); SetColor( 0 ); SetTextStyle( 2, 0, 0 ); OutTextXY( 342, 238, 'Find by airport code' ); DrawInputDataBox( 371, 270, 9 ); FindNum := InputNumericData( 371, 270, 9 , 0 ); if FindNum = 0 then begin MessageBox( 'Cancel search' ); BarDeluxe( 316, 200, 168, 110, 1, 23 ); Exit; end; for Counter := 1 to TotalRecords do if FindNum = Airport[ Counter ]^.Code then begin FindFlag := True; Inc( FNumCount ); FindBuffer[ FNumCount ] := Counter; end; end; if FindFlag then begin MessageBox( IntToStr( FNumCount ) + ' record(s) found' ); BarDeluxe( 316, 200, 168, 110, 1, 23 ); CurRec := 1; TabOfs := 1; CreateWindow( OperWinX, OperWinY, 522, 531, 'View Found Records' ); { Field for airport code } Area( OperWinX + 6, OperWinY + 35, 90, 420, 'Airport code' ); Panel( OperWinX + 19, OperWinY + 46, 62, 396, COLOR_3, COLOR_5, COLOR_1 ); { Field for airport full name } Area( OperWinX + 108, OperWinY + 35, 197, 420, 'Airport full name' ); Panel( OperWinX + 121, OperWinY + 46, 170, 396, COLOR_3, COLOR_5, COLOR_1 ); { Field for airport situation } Area( OperWinX + 318, OperWinY + 35, 198, 420, 'Airport situation' ); Panel( OperWinX + 332, OperWinY + 46, 170, 396, COLOR_3, COLOR_5, COLOR_1 ); { Status bar } PutDetatcher( OperWinX + 6, OperWinY + 496, 510 ); { Status bar } Panel( OperWinX + 6, OperWinY + 467, 85, 18, COLOR_3, COLOR_2, COLOR_1 ); SetColor( 0 ); OutTextXY( OperWinX + 12, OperWinY + 470, IntToStr( FNumCount ) + ' record(s)' ); SetColor( 0 ); SetTextStyle( 2, 0, 0 ); { Description } OutTextXY( OperWinX + 10, OperWinY + 508, 'ESC - Close | PageUp - Jump to begin of list | PageDown - Jump to end of list' ); OutputFoundRecords; repeat if KeyPressed then begin Key := ReadKey; if Key = ESC then begin BarDeluxe( OperWinX, OperWinY, 614, 531, 1, 23 ); { Clear & exit } Exit; end; if Key = #0 then begin Key := ReadKey; case Key of HOME_ext : if CurRec <> 1 then begin CurRec := 1; TabOfs := 1; RedrawFlag := True; OutputFoundRecords; end; END_ext : if CurRec <> FNumCount then if CurRec <= MaxRecsInWin then begin CurRec := MaxRecsInWin; RedrawFlag := True; OutputFoundRecords; end else begin CurRec := FNumCount; TabOfs := FNumCount - 27 ; RedrawFlag := True; OutputFoundRecords; end; UPARROW_ext : { Up to list } begin Dec( CurRec ); if CurRec = 0 then CurRec := 1; { List begin } if ( CurRec < TabOfs ) then begin Dec( TabOfs ); RedrawFlag := True; end; if TabOfs = 0 then TabOfs := 1; OutputFoundRecords; end; DOWNARROW_ext : { Down to list } begin Inc( CurRec ); if CurRec > FNumCount then CurRec := FNumCount; if ( CurRec > ( TabOfs + MaxRecsInWin - 1 ) ) then begin RedrawFlag := True; Inc( TabOfs ); end; if TabOfs > ( FNumCount - MaxRecsInWin + 1 ) then TabOfs := ( FNumCount - MaxRecsInWin + 1 ); OutputFoundRecords; end; end; { case Key } end; { Key = #0 } end; { KeyPressed } until False; end; if not FindFlag then begin MessageBox( '0 record(s) found' ); BarDeluxe( 316, 200, 168, 110, 1, 23 ); end; end; { of 'FindRecord' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure Help; Const HlpWinY = 100; Var HlpJmp : Byte; OldHlpJmp : Byte; begin HlpJmp := 1; CreateWindow( GetMaxX div 2 - 200, HlpWinY, GetMaxX div 2 , 446, 'Airport Administrator Help' ); SetColor( 0 ); SetTextStyle( 1, 0, 1 ); OutTextXY( GetMaxX div 2 - 180, HlpWinY + 30, 'Menu usage' ); SetTextStyle( 2, 0, 0 ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 65, 'When Airport Administrator is started, press ''Up'' or ''Down'' ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 80, 'key to select item of main menu. Press ''Down'' or ''Enter'' ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 95, 'key to call submenu. In submenu press ''Up'' or ''Down'' key to ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 110, 'select current item. If you want come back in main menu, ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 125, 'press ''Enter'' key on ''...''; otherwise you activate submenu ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 140,'item.' ); PutDetatcher( GetMaxX div 2 - 195, HlpWinY + 415, 389 ); SetColor( 0 ); OutTextXY( GetMaxX div 2 - 190, HlpWinY + 425, 'Esc - Close | Up - Back | Down - Next' ); SetColor( 25 ); OutTextXY( GetMaxX div 2 - 98, HlpWinY + 425, 'Up - Back' ); repeat if KeyPressed then begin Key := ReadKey; if Key = ESC then begin BarDeluxe( 5, 55, GetMaxX - 8, GetMaxY - 60, 1, 23 ); Exit; end; if Key = #0 then begin OldHlpJmp := HlpJmp; Key := ReadKey; case Key of UPARROW_ext : Dec( HlpJmp ); DOWNARROW_ext : Inc( HlpJmp ); end; { of case } end; if HlpJmp = 0 then HlpJmp := 1; if HlpJmp = 3 then HlpJmp := 2; if OldHlpJmp <> HlpJmp then begin BarDeluxe( GetMaxX div 2 - 185, HlpWinY + 30, 370, 380, 1, COLOR_2 ); case HlpJmp of 1 : begin SetColor( 0 ); SetTextStyle( 1, 0, 1 ); OutTextXY( GetMaxX div 2 - 180, HlpWinY + 30, 'Menu usage' ); SetTextStyle( 2, 0, 0 ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 65, 'When Airport Administrator is started, press ''Up'' or ''Down'' ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 80, 'key to select item of main menu. Press ''Down'' or ''Enter'' ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 95, 'key to call submenu. In submenu press ''Up'' or ''Down'' key to ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 110, 'select current item. If you want come back in main menu, ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 125, 'press ''Enter'' key on ''...''; otherwise you activate submenu ' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 140, 'item.' ); OutTextXY( GetMaxX div 2 - 190, HlpWinY + 425, 'Esc - Close | Up - Back | Down - Next' ); SetColor( 25 ); OutTextXY( GetMaxX div 2 - 98, HlpWinY + 425, 'Up - Back' ); end; 2 : begin SetColor( 0 ); SetTextStyle( 1, 0, 1 ); OutTextXY( GetMaxX div 2 - 180, HlpWinY + 30, 'Menu items description' ); SetTextStyle( 2, 0, 0 ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 65, 'File : Clear' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 80, 'Call dialog box. If you press ''Y'' or select ''Yes'' and press' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 95, '''Enter'' key, database will be remove. If you press ''N'' or' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 110, 'select ''No'' and press ''Enter'' then clear will be canceled.' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 140, 'Edit' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 155, 'Call ''Edition Manager''' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 170, 'Press ''Up'' or ''Down'' to select current record.'); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 195, '''Insert'' key allow to add record to list. If you wan''t' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 210, 'accept record, simply press ''Esc'' and record will not ad-' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 225, 'ded to database. When you will be ready add record, press' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 240, '''Insert'' key to add record in database. '); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 270, '''Enter'' key allow to edit current record. If you wan''t' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 285, 'accept edition press ''Esc'', otherwise press ''Insert'' to add.' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 300, '''Delete'' key allow to remove record from database.' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 315, '''Esc'' key close ''Edition Manager'' and refresh database.' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 330, '''Home'' key jump to begin of list.' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 345, '''End'' key jump to end of list.' ); OutTextXY( GetMaxX div 2 - 170, HlpWinY + 375, 'Find' ); OutTextXY( GetMaxX div 2 - 165, HlpWinY + 390, 'If record(s) was found you can see found record(s).' ); OutTextXY( GetMaxX div 2 - 190, HlpWinY + 425, 'Esc - Close | Up - Back | Down - Next' ); SetColor( 25 ); OutTextXY( GetMaxX div 2 - 17, HlpWinY + 425, 'Down - Next' ); end; end; { of case } end; end; until False; end; { of 'Help' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure Operations; begin CurRec := 1; { Current record } TabOfs := 1; CreateWindow( OperWinX, OperWinY, 522, 531, 'Edition Manager' ); { Field for airport code } Area( OperWinX + 6, OperWinY + 35, 90, 420, 'Airport code' ); Panel( OperWinX + 19, OperWinY + 46, 62, 396, COLOR_3, COLOR_5, COLOR_1 ); { Field for airport full name } Area( OperWinX + 108, OperWinY + 35, 197, 420, 'Airport full name' ); Panel( OperWinX + 121, OperWinY + 46, 170, 396, COLOR_3, COLOR_5, COLOR_1 ); { Field for airport situation } Area( OperWinX + 318, OperWinY + 35, 198, 420, 'Airport situation' ); Panel( OperWinX + 332, OperWinY + 46, 170, 396, COLOR_3, COLOR_5, COLOR_1 ); { Status bar } Panel( OperWinX + 6, OperWinY + 467, 122, 18, COLOR_3, COLOR_2, COLOR_1 ); PutDetatcher( OperWinX + 6, OperWinY + 496, 510 ); SetColor( 0 ); SetTextStyle( 2, 0, 0 ); { Description } OutTextXY( OperWinX + 10, OperWinY + 508, 'ESC - Close | Insert - Add record | Enter - Edit record | Delete - Remove record' ); OutputData; SetColor( 0 ); if TotalRecords = 0 then OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: 0 : 0 ' ) else OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: 1 : ' + IntToStr( TotalRecords ) ); repeat if KeyPressed then begin Key := ReadKey; if Key = ESC then { Close } begin BarDeluxe( OperWinX, OperWinY, 614, 531, 1, 23 ); { Clear & exit } Exit; end; if Key = ENTER then EditRecList( EditOp ); { Edit current record } if Key = #0 then begin Key := ReadKey; case Key of HOME_ext : if CurRec <> 1 then begin CurRec := 1; TabOfs := 1; RedrawFlag := True; OutputData; Panel( OperWinX + 6, OperWinY + 467, 122, 18, COLOR_3, COLOR_2, COLOR_1 ); SetColor( 0 ); OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); end; END_ext : if CurRec <> TotalRecords then if CurRec <= MaxRecsInWin then begin CurRec := MaxRecsInWin; RedrawFlag := True; OutputData; end else begin CurRec := TotalRecords; TabOfs := TotalRecords - 27 ; RedrawFlag := True; OutputData; Panel( OperWinX + 6, OperWinY + 467, 122, 18, COLOR_3, COLOR_2, COLOR_1 ); SetColor( 0 ); OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); end; UPARROW_ext : { Up to list } if TotalRecords = 0 then MessageBox( 'Database is empty' ) else begin SetColor( COLOR_2 ); { Erase old value of records counter } OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); Dec( CurRec ); if CurRec = 0 then CurRec := 1; { List begin } SetColor( 0 ); OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); if ( CurRec < TabOfs ) then begin Dec( TabOfs ); RedrawFlag := True; end; if TabOfs = 0 then TabOfs := 1; OutputData; end; {............................................................................} DOWNARROW_ext : { Down to list } if TotalRecords = 0 then MessageBox( 'Database is empty' ) else begin SetColor( COLOR_2 ); OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); Inc( CurRec ); if CurRec > TotalRecords then CurRec := TotalRecords; SetColor( 0 ); OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); if ( CurRec > ( TabOfs + MaxRecsInWin - 1 ) ) then begin RedrawFlag := True; Inc( TabOfs ); end; if TabOfs > ( TotalRecords - MaxRecsInWin + 1 ) then TabOfs := ( TotalRecords - MaxRecsInWin + 1 ); OutputData; end; {............................................................................} DELETE_ext : if TotalRecords = 0 then MessageBox( 'Database is empty' ) else case DialogBox( 'Remove selected record?', 1 ) of { Default 'No' } 0 : { Remove selected record } begin Dec( TotalRecords ); Dispose( Airport[ CurRec ] ); for Counter := CurRec to TotalRecords do Airport[ Counter ] := Airport[ Counter + 1 ]; SortDatabase; if CurRec >= TotalRecords then CurRec := TotalRecords; if TabOfs > 1 then Dec( TabOfs ); RedrawFlag := True; OutputData; Panel( OperWinX + 6, OperWinY + 467, 122, 18, COLOR_3, COLOR_2, COLOR_1 ); SetColor( 0 ); OutTextXY( OperWinX + 12, OperWinY + 470, 'Record: ' + IntToStr( CurRec ) + ' : ' + IntToStr( TotalRecords ) ); if TotalRecords = 0 then { Database is empty } begin BarDeluxe( OperWinX + 21, OperWinY + 34 + 1 * 14, 58, 14, 1, COLOR_5 ); BarDeluxe( OperWinX + 123, OperWinY + 34 +1 * 14, 166, 14, 1, COLOR_5 ); BarDeluxe( OperWinX + 334, OperWinY + 34 +1 * 14, 166, 14, 1, COLOR_5 ); end; if ( CurRec > 1 ) and ( TabOfs = 1 ) then begin BarDeluxe( OperWinX + 21, OperWinY + 34 + CurRec * 14, 58, 14, 1, COLOR_4 ); BarDeluxe( OperWinX + 123, OperWinY + 34 + CurRec * 14, 166, 14, 1, COLOR_4 ); BarDeluxe( OperWinX + 334, OperWinY + 34 + CurRec * 14, 166, 14, 1, COLOR_4 ); SetColor( 15 ); OutTextXY( OperWinX + 24, OperWinY + 34 + CurRec * 14, IntTOStr( Airport[ TabOfs + CurRec - 1 ]^.Code ) ); OutTextXY( OperWinX + 126, OperWinY + 34 + CurRec * 14, Airport[ TabOfs + CurRec - 1 ]^. FullName ); OutTextXY( OperWinX + 337, OperWinY + 34 + CurRec * 14, Airport[ TabOfs + CurRec - 1 ]^. Situation ); end; end; end; { case DialogBox /Delete/ } {............................................................................} INSERT_ext : EditRecList ( AddOp ); end; { case Key } end; end; until False; end; { of 'Operations' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure OutputData; begin MaxRecsInWin := 28; if MaxRecsInWin > TotalRecords then MaxRecsInWin := TotalRecords; for Counter := 1 to MaxRecsInWin do begin if RedrawFlag then begin { Clean fields when scroll } BarDeluxe( OperWinX + 21, OperWinY + 48, 58, 392, 1, COLOR_5 ); BarDeluxe( OperWinX + 123, OperWinY + 48, 166, 392, 1, COLOR_5 ); BarDeluxe( OperWinX + 334, OperWinY + 48, 166, 392, 1, COLOR_5 ); end; if ( TabOfs + Counter - 1 ) <> CurRec then begin BarDeluxe( OperWinX + 21, OperWinY + 34 + Counter * 14, 58, 14, 1, COLOR_5 ); BarDeluxe( OperWinX + 123, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_5 ); BarDeluxe( OperWinX + 334, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_5 ); SetColor( 0 ); OutTextXY( OperWinX + 24, OperWinY + 34 + Counter * 14, IntToStr( Airport[ TabOfs + Counter - 1 ]^.Code ) ); OutTextXY( OperWinX + 126, OperWinY + 34 + Counter * 14, Airport[ TabOfs + Counter - 1 ]^.FullName ); OutTextXY( OperWinX + 337, OperWinY + 34 + Counter * 14, Airport[ TabOfs + Counter - 1 ]^.Situation ); RedrawFlag := False; end else begin BarDeluxe( OperWinX + 21, OperWinY + 34 + Counter * 14, 58, 14, 1, COLOR_4 ); BarDeluxe( OperWinX + 123, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_4 ); BarDeluxe( OperWinX + 334, OperWinY + 34 + Counter * 14, 166, 14, 1, COLOR_4 ); SetColor( 15 ); OutTextXY( OperWinX + 24, OperWinY + 34 + Counter * 14, IntTOStr( Airport[ TabOfs + Counter - 1 ]^.Code ) ); OutTextXY( OperWinX + 126, OperWinY + 34 + Counter * 14, Airport[ TabOfs + Counter - 1 ]^. FullName ); OutTextXY( OperWinX + 337, OperWinY + 34 + Counter * 14, Airport[ TabOfs + Counter - 1 ]^. Situation ); RedrawFlag := False; end; end; end; { of 'OutputData' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure Quit; begin case DialogBox( 'Do you really want to quit?', 0 ) of { Default 'Yes' } 0 : begin CloseGraph; for Counter := 1 to TotalRecords do Dispose( Airport[ Counter ] ); Halt; end; 1 : Exit; end; { case } end; { of 'Quit'} {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure ReadData; Var Question : String; begin Assign( F, DATAFILENAME ); {$I-} Reset( F, 1 ); {$I+} if IOResult <> 0 then begin Textbackground( 1 ); ClrScr; TextColor( 14 ); WriteLn( 'Airport Administrator v.1.0' ); TextColor( 15 ); WriteLn; WriteLn( 'Data initialization failure' ); WriteLn( 'Cannot found file "data.adb"' ); WriteLn; repeat GoToXY( 1, 6 ); Write( ' ' ); GoToXY( 1, 7 ); Write( ' ' ); GoToXY( 1, 6 ); Write( 'Create new empty ADB file (Y/N)? ' ); ReadLn( Question ); until ( Question = 'y' ) or ( Question = 'Y' ) or ( Question = 'n' ) or ( Question = 'N' ); if ( Question = 'y' ) or ( Question = 'Y' ) then begin TotalRecords := 0; Assign( F, DATAFILENAME ); {$I-} Rewrite( F, 1 ); {$I+} Blockwrite( F, TotalRecords, 5 ); Close( F ); end; if ( Question = 'n' ) or ( Question = 'N' ) then begin TextBackground( 0 ); TextColor( 7 ); ClrScr; WriteLn( 'Program terminated' ); Halt; end; end else { Data file was found } Textbackground( 0 ); ClrScr; TextColor( 7 ); Assign( F, DATAFILENAME ); {$I-} Reset( F, 1 ); {$I+} BlockRead( F, TotalRecords, 5 ); for Counter := 1 to TotalRecords do begin New( Airport[ Counter ] ); BlockRead( F, Airport[ Counter ]^.Code, 9 ); BlockRead( F, Airport[ Counter ]^.FullName, 28 ); BlockRead( F, Airport[ Counter ]^.Situation, 28 ); end; Close( F ); end; { of 'ReadData' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure RefreshDatabase; begin Assign( F, DATAFILENAME ); {$I-} Reset( F, 1 ); {$I+} BlockWrite( F, TotalRecords, 5 ); for Counter := 1 to TotalRecords do begin BlockWrite( F, Airport[ Counter ]^.Code, 9 ); BlockWrite( F, Airport[ Counter ]^.FullName, 28 ); BlockWrite( F, Airport[ Counter ]^.Situation, 28 ); end; Close( F ); end; { of 'RefreshData' } {----------------------------------------------------------------------------} {----------------------------------------------------------------------------} Procedure SortDatabase; Var I : Integer; J : Integer; TempCode : LongInt; TempName : String; TempSit : String; begin for I := 1 to TotalRecords do for J := I to TotalRecords do begin if Airport[ I ]^.COde > Airport[ J ]^.Code then begin TempCode := Airport[ I ]^.Code; TempName := Airport[ I ]^.FullName; TempSit := Airport[ I ]^.Situation; Airport[ I ]^.Code := Airport[ J ]^.Code; Airport[ I ]^.FullName := Airport[ J ]^.FullName; Airport[ I ]^.Situation := Airport[ J ]^.Situation; Airport[ J ]^.Code := TempCode; Airport[ J ]^.Fullname := TempName; Airport[ J ]^.Situation := TempSit; end; end; RefreshDatabase; end; { of 'SortDatabase' } {----------------------------------------------------------------------------} End.{ of unit 'AirLib' }