// Değişkenler, fonksiyonlar ve procedureler ilk harfleri küçük diğer kelime başlangıcı Büyük gerisi küçük harf // ile tanımlanır.
// Dile ayrılmış karakter dizilerinin ilk harfleri büyük başlar.(readln, write, if else hariç)

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

// Yol Bilgisayarı -> Menzil menüsünde = Depoda kalan benzin ile alına bilinecek en fazla yol değeri // // //gösteriliyor.
// Yol Bilgisayarı -> Ortalama hiz menüsünde = Yerel km bilgisinin aracın sürüldüğü toplam zamana // // //bölünmesiyle ortalama hız değeri belirleniyor.
// Yol Bilgisayarı -> Ortalama yakıt tüketimi menüsünde = Yakılan toplam yakıt miktarının kat edilen toplam //100 km değerine bölünmesiyle alde edildi.

{*******************************************************************************}
 
// Eksik yön = Kullanıcıdan Integer yada Real tipinde istenen değerlere farklı türden veriler girildiği durumlar için program işlevsiz kalır
// kısaca girilen veri türlerinin kontrolü yapılmamıştır.
// Değişken  isimleri anlaşılsın diye kısaltmasız uzun olarak tanımlandı
// YolBilgisayari Sınıfından oluşturulan yolBilgisayariNesne isimli nesne kısaltılarak yBN şeklinde kullanıldı.
   
{*******************************************************************************}


Program yolBilgisayari;
// Kütüphane tanımları.
 Uses crt;
 Uses dos;


   {-- SINIF TANIMLAMA BLOĞU --}
   type
 
    yolBilgisayari = class // Sınıfın adı =  yolBilgisayari .
 
    private
          surulenZaman     : Real; // Aracın toplam sürüldüğü saat bilgisini tutar.
          kalanBenzin      : Real; // Depoda kalan yakıt.
          tuketilenYakit   : Real; // Aracı sürerken tüketilen toplam yakıt miktarını tutar.
          yerelKm          : Integer; // Aracın sürüldüğü yerel km değeri.
          genelKm          : Integer; // Aracın sürüldüğü genel km değeri.
         
    public
         secimAmenu       : Char; // Ana menüsünden seçilen değeri tutmak için oluşturuldu.
         secimImenu       : Char; // İşlemler menüsünden seçilen değeri tutmak için oluşturuldu.
         secimYmenu       : Char; // Yol bilgisayarı menüsünden seçilen değeri tutmak için oluşturuldu.
         
         constructor kurucu;
       
{*******************************************************************************}
   // Procedure tanımlamaları(Prototipleri).
                             
         //Açıklama için yazılan procedure.
        Procedure aciklama;
 
         // Ana menü tercihini alan Procedure.
        Procedure anaMenu(Var secim : Char); // kontrol : Boolean;

         // İşlemler menüsü tercihini alan Procedure.
        Procedure islemMenusu(Var secim : Char);
 
         // Yol bilgisayari menüsü tercihini alan Procedure.
        Procedure yolBilgisayariMenusu(Var secim : Char);            

{*******************************************************************************}
   // İşlemler menüsü görevlerini yapmak için yazılan Procedure (Prototipleri).
 
         // Kullanıcıdan ortalama hızı ve Katedilecek yol bilgisini alan Procedure.
        Procedure araciSur;

         // Kullanicidan depoya konulucak benzini litre cinsinden alan Procedure.
        Procedure benzinAl;

         // Ortalama hız değerini kullanıcıya gösteren Procedure.
        Procedure yerelKmSifirla;

{*******************************************************************************}
   // Yol Bilgisayarı  menüsü görevlerini yapmak için yazılan Procedure (Prototipleri).    
       
         //Gerel km değerini kullanıcıya gösteren Procedure.
        Procedure genelKmGoster;

         // Yerel km degerini sifirlayan Procedure.
        Procedure yerelKmGoster;

         // Ortalam hız degerini gösteren Procedure.
        Procedure ortalamaHizGoster;
 
         // Depodaki yakıt değerini gösteren Procedure.
        Procedure depodakiYakitGoster;

         // Depodaki yakıt ile katedile bilinecek en fazla mesafeyi kullanıcıya gösterir.
        Procedure menzilGoster;
 
         //Ortalama yakıt tükettimini kullanıcıya gösteren Procedure.
        Procedure ortalamaYakitTuketimiGoster;  
   end;


   {-- SINIF FONKSİYONLARININ TANIMI --}
 
  // Kurucu constructor.
   constructor yolBilgisayari.kurucu;
     Begin
       surulenZaman     := 0;
       kalanBenzin      := 0;
       tuketilenYakit   := 0;
       yerelKm          := 0;
       genelKm          := 0;
       secimAmenu       := '0';
       secimImenu       := '0';
       secimYmenu       := '0';
     End;
 
 
{*******************************************************************************}
   // İşlemler menüsü görevlerini yapmak için yazılan Procedure govdeleri.

  // Kullanıcıdan ortalama hızı ve Katedilecek yol bilgisini alan Procedure.
  //  En uzun Procedure tanımıdır ve birçok işlem burada yapılıyor.
   Procedure yolBilgisayari.araciSur;
   Var alinanKm             : Integer; // O an kullanıcının girdiği gidilecek yol verisi.
   Var ortalamSurusHizi     : Integer; // O an kullanıcının girdiği aracın belirtilen yol boyunca sürüldüğü ortalama hız verisi.
   Var secilenHizDegerTut   : Byte; // Her 100 km'de kaç litre yakıt tüketileceğini tutumak için tanımlandı.
   Var alinabilirYolKontrol : Boolean; // Girilen gidilecek olan ortalama hiz ve (yorum devamı bir alt satırda.)
                                                        // alınacak yol bilgilerinin kontrolü için tanımlandı.
   Begin  
     alinabilirYolKontrol := False;
     if (kalanBenzin <> 0) Then
     Begin
       Repeat          
         write('Gidilecek olan ortalama hizi giriniz(km/h turunde) = ');
         readln(ortalamSurusHizi);
           if (0 < ortalamSurusHizi) And (ortalamSurusHizi <= 240) Then writeln('Araci sureceginiz ortalama hiz = ', ortalamSurusHizi)        
           else
             Begin
               writeln('Yanlis ortalama surus hizi verisi girdiniz! Tekrar deneyiniz.');
               Continue;
             End;
               
         if (0 <= ortalamSurusHizi) And (ortalamSurusHizi < 50) Then
           Begin
             writeln('Araci surus hizini ', ortalamSurusHizi, 'km girdin. Dostum sen kaplunbaga kadar yavassin!');
             secilenHizDegerTut := 1;
           End
         else if (50 <= ortalamSurusHizi) And (ortalamSurusHizi < 75) Then
           Begin
             secilenHizDegerTut := 2;
           End
         else if (75 <= ortalamSurusHizi) And (ortalamSurusHizi < 110) Then
           Begin          
             secilenHizDegerTut := 3;    
           End
         else if (110 <= ortalamSurusHizi) And (ortalamSurusHizi <= 240) Then
           Begin
             writeln('Dostum sen eceline susamissin!');
             secilenHizDegerTut := 4;    
           End;
       Until ((0 < ortalamSurusHizi) And (ortalamSurusHizi <= 240));
   
       // Katedilecek yol ve tüketilen toplam yakıt miktarının tutulduğu yer.
       Repeat
         write('Katedilecek olan yol bilgisini giriniz(km turunde) = ');
         readln(alinanKm);
     
         if (secilenHizDegerTut = 1) And (alinanKm <= ((kalanBenzin * 20) / 3)) Then
           Begin          
             alinabilirYolKontrol := True;
             tuketilenYakit := tuketilenYakit + ((3 * alinanKm) / 20);
             kalanBenzin    := kalanBenzin - ((3 * alinanKm) / 20);
           End
         else if (secilenHizDegerTut = 2) And (alinanKm <= ((kalanBenzin * 100) / 9)) Then
           Begin
             alinabilirYolKontrol := True;
             tuketilenYakit := tuketilenYakit + ((9 * alinanKm) / 100);
             kalanBenzin    := kalanBenzin - ((9 * alinanKm) / 100);
           End
         else if (secilenHizDegerTut = 3) And (alinanKm <= ((kalanBenzin * 50) / 3)) Then
           Begin          
             alinabilirYolKontrol := True;
             tuketilenYakit := tuketilenYakit + ((3 * alinanKm) / 50);
             kalanBenzin    := kalanBenzin - ((3 * alinanKm) / 50);    
           End
         else if (secilenHizDegerTut = 4) And (alinanKm <= ((kalanBenzin * 25) / 3)) Then
           Begin
             alinabilirYolKontrol := True;
             tuketilenYakit := tuketilenYakit + ((3 * alinanKm) / 25);
             kalanBenzin    := kalanBenzin - ((3 * alinanKm) / 25);    
           End
         else writeln('Malesef girilen ortalama surus hizi ve alinacak yol bilgileri icin depodaki benzin yetersiz.');          
       Until (alinabilirYolKontrol = True);
       
         if (alinabilirYolKontrol = True) Then
           Begin
             Writeln('Alinacak yol ', alinanKm ,' km, ortalama hiziniz ',ortalamSurusHizi,' km/h.');
             surulenZaman := surulenZaman + (alinanKm / ortalamSurusHizi);
             yerelKm := yerelKm + alinanKm;
             genelKm := genelKm + alinanKm;
             alinanKm := 0;
           End;      
     End
     else writeln('Depoda benzin yok, araci suremezsiniz!');        
   End;
 
  // Kullanicidan depoya konulucak benzini litre cinsinden alan Procedure.
   Procedure yolBilgisayari.benzinAl;
   Var alinanbenzin : Real;
     Begin
       Repeat
         writeln('Depodaki bennzin miktari =', kalanBenzin :2 :2);  
         write('Alinacak olan benzini giriniz.(Litre turunde)= ');
         readln(alinanbenzin);
         kalanBenzin := kalanBenzin + alinanbenzin;
           if (0 <= kalanBenzin) And (kalanBenzin <= 60) Then
             Begin
               writeln('Aldiginiz benzin ', alinanbenzin :2 :2, ' lt.', ' Depoda ', kalanBenzin :2 :2, ' lt benzin var.');
             End
           else
             Begin
               writeln('Aldiginiz benzin miktari deponun kapasitesini asiyor(yada yanlis deger girdiniz)!');
               kalanBenzin := kalanBenzin - alinanbenzin;
               Continue;
             End;
       Until (0 <= kalanBenzin) And (kalanBenzin <= 60);
     End;

 
  // Yerel km degerini sifirlayan Procedure.
   Procedure yolBilgisayari.yerelKmSifirla;
     Begin
       write('Yerel km degerenin ilk degeri = ', yerelKm);
       yerelKm := 0;
       write('Yerel km degeri sifirlandi. Yerelkm= ', yerelKm);    
     End;

{*******************************************************************************}
   // Yol Bilgisayarı menüsü görevlerini yapmak için yazılan Procedure gövdeleri.
   
   // Genel km degerini kullanıcıya gösteren Procedure.
   Procedure yolBilgisayari.genelKmGoster;
     Begin  
       write('Arac uretildiginden itibaren gidilen km bilgisi = ', genelKm);      
     End;
 
 
   // Yerel km degerini kullanıcıya gösteren Procedure.
   Procedure yolBilgisayari.yerelKmGoster;
     Begin  
       write('Yerel km bilgisinin son sifirlanmasindan itibaren gidilen km bilgisi = ', yerelKm);      
     End;


  // Ortalama hız degerini kullanıcıya gösteren Procedure.
   Procedure yolBilgisayari.ortalamaHizGoster;
   Var ortalamaHiz : Real;
     Begin
       if (yerelKm <> 0) And (surulenZaman <> 0) Then
       Begin
         ortalamaHiz := (yerelKm / surulenZaman);        
         if (ortalamaHiz <> 0) Then writeln('Girilen son veriye göre ortalama hiz bilgisi = ', ortalamaHiz :2 :2)
         else if (ortalamaHiz = 0) Then writeln('Daha arabayi surmemissiniz!');    
       End
       else writeln('Yerel km degeri 0 oldugu icin yapmis oldugunuz istek gecersiz.');
     End;
 
 
  // Depoda kalan yakıt değerini kullanıcıya gösteren Procedure.
   Procedure yolBilgisayari.depodakiYakitGoster;
     Begin  
       write('Depoda kalan yakit miktari bilgisi = ', kalanBenzin :2 :2, ' litre.');      
     End;

 
  // Ortalama yakıt tüketimini kullanıcıya gösteren procedure.
   Procedure yolBilgisayari.ortalamaYakitTuketimiGoster;
   Var ortalamaYakitTuketimi : Real;
     Begin
       if (tuketilenYakit <> 0) Then
         Begin
           ortalamaYakitTuketimi := (tuketilenYakit / (genelKm / 100));
           writeln('Ortalama yakit tuketimi(Her 100 km de harcanan ortalama benzin)= ', ortalamaYakitTuketimi :2 :2);
         End
       else writeln('Daha hic arac surup yakit tuketmediniz! Isteginize cevap verilemiyor.');
     End;
 
 
  // Depoda kalan yakıt ile hıza göre gidile bilinicek yol bilgisini veirir.
   Procedure yolBilgisayari.menzilGoster;
   Var ortalamaHiz : Real;
   Var menzil      : Real;
     Begin  
       if (yerelKm <> 0) And (surulenZaman <> 0) Then
         Begin
           ortalamaHiz := (yerelKm / surulenZaman);
                if (0 < ortalamaHiz) And (ortalamaHiz < 50)      Then menzil := ((20  * kalanBenzin) / 3)
           else if ( 50 <= ortalamaHiz) And (ortalamaHiz <  75 ) Then menzil := ((100 * kalanBenzin) / 9)
           else if ( 75 <= ortalamaHiz) And (ortalamaHiz <  110) Then menzil := ((50  * kalanBenzin) / 3)
           else if (110 <= ortalamaHiz) And (ortalamaHiz <= 240) Then menzil := ((100 * kalanBenzin) / 9);
     
           writeln('Depoda kalan yakit miktari bilgisi = ', kalanBenzin :2 :2);
           writeln('Ortalama hiz degeri = ', ortalamaHiz :2 :2);
           writeln('Bu hizla giderseniz deponuzdaki benzin ile ', menzil :2 :2, ' km yol gide bilirsiniz.');
         End      
       else writeln('yerelKm = 0 yada surulenZaman = 0 degerlerine sahip oldugundan isteginiz gecersizdir!');    
     End;
 

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

   // Procedure ve Fonction gövdeleri.

   //Açıklama için yazılan procedure.
   Procedure yolBilgisayari.aciklama;
     Begin
      writeln('**************************************************************************');
      writeln('  Benzin deposu kapasitesi 60 litredir.');
      writeln('  Aracin en fazla hizi 240 km/h.');
      writeln('  Hiza gore benzin tuketilir, her 100 km de yakilan benzin litre cinsinden:');
      writeln('  0-50 hiz 100 kilometrede 15 litre, 50-75 hiz 100 kilometrede 9 litre');
      writeln('  75-110 hiz 100 kilometrede 6 litre, 110-240 hiz 100 kilometrede 12 litre');
      writeln('*************************************************************************');
      writeln('  Kalan benzin ilk basta 0 litredir.');
      writeln('  Yerel kilometre 0 km.');
      writeln('  Genel kilometre 0 km');
      writeln('  Yerel km sifirlana bilir ancak genel km sifirlanamaz');
      write('**************************************************************************');
      readKey;    
     End;
 
 
   // Ana menü tercihi alınıyor.
   Procedure yolBilgisayari.anaMenu;
   Var kontrol : Boolean;      
     Begin  
       Clrscr;
       kontrol := False;
       writeln('*************--Ana Menu--*************');
       writeln('   *_Islemler icin -> 1' );
       writeln('   *_Yol bilgisayari icin -> 2');
       writeln('   *_Cikis icin -> 3');
       writeln('=================================================================');
                                                       
       Repeat      
         write('Ana menuden seciminizi yapiniz = ');
         secim := readKey; // Seçim değişkenine klavyeden girilen değer atanmıştır.            
         writeln(secim);
           if secim = '1'      Then kontrol := True
           else if secim = '2' Then kontrol := True
           else if secim = '3' Then kontrol := True
           else
             Begin
               writeln('Yanlis deger girdiniz! Tekrar deneyin. ');
               Continue;
             End;                                                                                                                                            
       Until (kontrol = True);                                  
     End;


   // İşlemler menüsü tercihi alınıyor.
   Procedure yolBilgisayari.islemMenusu;
   Var kontrol : Boolean;        
     Begin
       Clrscr;
       kontrol := False;    
       writeln('Seciminiz 1;');
       writeln('*********************************************');
       writeln('*************--Islemler Menusu--*************');
       writeln('   *_Araci sur -> 1');
       writeln('   *_Benzin al -> 2');
       writeln('   *_Yerel km bilgisini sifirla -> 3');
       writeln('   *_Ana menuye don. -> 4');
       writeln('==============================================================================');
                                                       
      Repeat    
        write('Islemler menusunden seciminizi yapiniz = ');
        secim := readKey; // Seçim değişkenine klavyeden girilen değer atanmıştır.            
        writeln(secim);      
          if secim = '1'      Then kontrol := True
          else if secim = '2' Then kontrol := True
          else if secim = '3' Then kontrol := True
          else if secim = '4' Then kontrol := True
          Else
            Begin
              writeln('Yanlis deger girdiniz! Tekrar deneyin. ');
              Continue;
            End;                                                                                        
      Until (kontrol = True);                                
   End;


  // Yol bilgisayari menüsü tercihi alınıyor.
   Procedure yolBilgisayari.yolBilgisayariMenusu;
   Var kontrol : Boolean;
     Begin
       Clrscr;
       kontrol := False;
       writeln('Seciminiz 2;');
       writeln('****************************************************');
       writeln('*************--Yol bilgisayari Menusu--*************');
       writeln('   *_Genel km goster -> 1');
       writeln('   *_Yerel km goster -> 2');
       writeln('   *_Ortalama hiz -> 3');
       writeln('   *_Ortalama yakit tuketimi -> 4');
       writeln('   *_Depodaki yakit -> 5');
       writeln('   *_Menzil -> 6');
       writeln('   *_Ana menuye don. -> 7');
     
       writeln('===============================================================');
                                                       
      Repeat              
        write('Yol bilgisayari menusunden seciminizi yapiniz = ');
        secim := readKey; // Seçim değişkenine klavyeden girilen değer atanmıştır.            
        writeln(secim);
     
          if secim = '1'      Then kontrol := True
          else if secim = '2' Then kontrol := True
          else if secim = '3' Then kontrol := True
          else if secim = '4' Then kontrol := True
          else if secim = '5' Then kontrol := True
          else if secim = '6' Then kontrol := True
          else if secim = '7' Then kontrol := True
          Else
            Begin
              writeln('Yanlis deger girdiniz! Tekrar deneyin. ');
              Continue;
            End;
                                                                                       
      Until (kontrol = True);                                  
   End;

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

                                                         
   // Ana program bloğu.
    Begin
 
     Var yBN : yolBilgisayari; // Nesne tanımlanıyor (yolBilgisayariNesne = yBN).
     yBN := yolBilgisayari.kurucu; // Nesne oluşturuluyor.
   
     //yBN.ilkDegerAta; //
                   
     // Ana program başlangıcı.
     yBN.aciklama;
   
        Repeat // Menu Dongu kisimi baslangici.      
          yBN.anaMenu(yBN.secimAmenu); // Bu fonksiyon ile ana menü seçimi alınıyor.
         
         // Menüler arasındaki geçiş kontrolleri.        
          Case yBN.secimAmenu of
            '1' : Begin
                     Repeat                                          
                         yBN.islemMenusu(yBN.secimImenu);                      
                         readkey;
                       
                         Case yBN.secimImenu of          
                           '1' : Begin
                                   yBN.araciSur;//Araci sur fonksiyonu gelecek.
                                 End;
                           '2' : Begin
                                   yBN.benzinAl; //Benzin al fonksiyonu gelecek.
                                 End;
                           '3' : Begin
                                   yBN.yerelKmSifirla;//Yerel km sifirla fonksiyonu gelecek.
                                 End;
                           '4' : Begin
                                   writeln('Ana menuye donuluyor.');                      
                                 End;                        
                         End;
                       
                         readKey;                                  
                     Until (yBN.secimImenu = '4');                            
                        Continue; // Ana menü'ye geri dönmek için yazıldı.
                                             
                  End;
                     
             '2' : Begin                
                     Repeat                                                            
                         yBN.yolBilgisayariMenusu(yBN.secimYmenu);
                       
                         readkey;
                         Case yBN.secimYmenu of          
                           '1' : Begin                      
                                   yBN.genelKmGoster // write('Genel km goster fonksiyonunu cagir.')
                                 End;
                           '2' : Begin
                                   yBN.yerelKmGoster // write('Yerel km goster fonksiyonunu cagir.')
                                 End;
                           '3' : Begin
                                   yBN.ortalamaHizGoster // write('Ortalama hız fonksiyonunu cagir.')
                                 End;
                           '4' : Begin
                                   yBN.ortalamaYakitTuketimiGoster // write('Ortalama yakit tuketimi gosteren                                        fonksiyonu cagir.')
                                 End;
                           '5' : Begin
                                   yBN.depodakiYakitGoster //write('Depoda ki yakitgoster fonksiyonunu cagir.')
                                 End;
                           '6' : Begin
                                   yBN.menzilGoster //write('Menzil goster fonksiyonunu cagir.')
                                 End;
                           '7' : Begin
                                   write('Ana menute donuluyor.');
                                 End;
                         End;
                       
                         readkey;                      
                     Until (yBN.secimYmenu = '7');                                              
                     Continue; // Ana menü'ye geri dönmek için yazıldı.
                   End;
       
              '3' : Begin
                      writeln('Programdan cikis yapildi.');
                    End;
          End;        
        Until (yBN.secimAmenu = '3'); // Menu Dongu kisimi sonu.      
        readKey;  
    End.