aboutsummaryrefslogblamecommitdiffstats
path: root/Game/Code/Screens/UScreenEditSub.pas
blob: 41b66d50750d92d6b7b347e76a9bbdf2cbf05ca8 (plain) (tree)
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756





































                                                                                                   

                                 
                                 


                                 













                                 

                             





                                                                       
 
                         
                                         





























                                                                                                          
                                                                                                       


















                                                                                                         





                                                                    
































































































































































































































                                                                                                                  
                                      









                                                                     
                                  



                                                                                                    
                                      








                                                                     

                                   




                                             
                                      








                                                                                                              
                                    















                                                                                                    
                                      








                                                                     

                                   









































































































                                                                                                                  






                                                          





                                                                                                    
                                      






                                                                                      
                                    






                                                   
                                      


                                        
                                  







                                                                                    
                                      





                                                                                    
                                  












                                                                                                    
                                      






                                                                            
                                    






                                                                
                                      

                                   
                                  








                                                                                    
                                      





                                                                                    
                                  























                                                                                              

                                       

                                   
                                  







                                                                                               

                                       




                                                                                               

                                   














                                                                                                    


                                      









































                                                                                               
















                                                                                                  














































                                                                                   
             
 










                                                                                 

                                                                                                  
                                    


                                 
                                
 

















































                                                                                    
             
 

                 

                                                                                                  
                                    


                                 
                                
 

                                         









                                                                     










                                                  







                                                                                                  

                                         









                                                                     








































                                                                               
                                             







                                                                                
                                             


















































































                                                                                                                 


















































                                                                                                                








                                                                                
























                                                                                                
























































































































































































































































                                                                                                                                   













                                                                                                  
                                                 

                


























































































































































































































































































































































                                                                                                                             








                                                                                          













































































































































                                                                                                   



























































                                                                                              



                                                                                                         


                                                              






























                                                                                                                                                                           
                                                        















































































                                                                                                   
unit UScreenEditSub;

interface

uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
  ULyrics, Math, gl, UThemes, MidiOut, UHelp;

type
  TMedleyNotes = record
    start: TPos;
    end_: TPos;
    Preview: TPos;
    isStart: boolean;   //start beat is declared
    isEnd: boolean;     //end beat is declared
  end;

  TScreenEditSub = class(TMenu)
    const
      ID='ID_001';   //for help system

    private
      //Variable is True if no SOng is loaded 
      Error:        Boolean;
      MP3Volume:    Integer;
      
      TextNote:     integer;
      TextSentence: integer;
      TextTitle:    integer;
      TextArtist:   integer;
      TextMp3:      integer;
      TextBPM:      integer;
      TextGAP:      integer;
      TextDebug:    integer;
      TextNStart:   integer;
      TextNDlugosc: integer;
      TextNTon:     integer;
      TextNText:    integer;
      AktNuta:      integer;

      PlaySentence:     boolean;
      PlaySentenceMidi: boolean;
      PlayOneNote:      boolean;
      PlayOneNoteMidi:  boolean;

      PlayStopTime: real;
      LastClick:    integer;
      Click:        boolean;
      CopySrc:      integer;

      MidiOut:      TMidiOutput;
      MidiStart:    real;
      MidiStop:     real;
      MidiTime:     real;
      MidiPos:      real;
      MidiLastNote: integer;


      TextEditMode: boolean;
      BPMEditMode:  boolean;

      MedleyNotes:  TMedleyNotes;

      editText:     string; //backup of current text in text-edit-mode
      noteStart:    integer; //Start note when playing sentence
      LineChanged:  boolean;


      procedure NewBeat;
      procedure ChangeBPM(newBPM: real);
      procedure CzesciDivide;
      procedure CzesciMultiply;
      procedure LyricsCapitalize;
      procedure LyricsCorrectSpaces;
      procedure FixTimings;
      procedure DivideSentence;
      procedure JoinSentence;
      procedure DivideNote;
      procedure DeleteNote;
      procedure TransposeNote(Transpose: integer);
      procedure ChangeWholeTone(Tone: integer);
      procedure MoveAllToEnd(Move: integer);
      procedure MoveTextToRight;
      procedure MarkSrc;
      procedure PasteText;
      procedure CopySentence(Src, Dst: integer);
      procedure CopySentences(Src, Dst, Num: integer);
      //Note Name Mod
      function GetNoteName(Note: Integer): String;
      function GetMedleyLength: real; //returns if availible the length of the medley in seconds, else 0
    public
      Tex_Background:     TTexture;
      FadeOut:            boolean;
      Path:               string;
      FileName:           string;
      SongIndex:          integer; //SongIndex from CatSongs.Song
      constructor Create; override;
      procedure onShow; override;
      function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
      function ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
      function ParseInputEditBPM(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
      function Draw: boolean; override;
      procedure onHide; override;
  end;

implementation
uses UGraphic, UDraw, UMain, USkins, ULanguage;

// Method for input parsing. If False is returned, GetNextWindow
// should be checked to know the next window to load;
function TScreenEditSub.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
  SDL_ModState:  Word;
  R:    real;
  SResult: boolean;
begin
  Result := true;

  Text[TextDebug].Text := '';

  if TextEditMode then
    Result := ParseInputEditText(PressedKey, ScanCode, PressedDown)
  else if BPMEditMode then
    Result := ParseInputEditBPM(PressedKey, ScanCode, PressedDown)
  else
  begin

  SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
    + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT  + KMOD_RALT {+ KMOD_CAPS});

  If (PressedDown) then begin // Key Down
    case PressedKey of
      SDLK_TAB:
        begin
          ScreenPopupHelp.ShowPopup();
        end;

      SDLK_ESCAPE:
        begin
          FadeTo(@ScreenSong);
        end;

      SDLK_Q:
        begin
          Result := false;
        end;

      SDLK_BACKQUOTE:
        begin
          // Increase Note Length (same as Alt + Right)
          Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
          if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
            Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
        end;

      SDLK_EQUALS:
        begin
          // Increase BPM
          if SDL_ModState = 0 then
            AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) + 1) / 5; // (1/20)
          if SDL_ModState = KMOD_LSHIFT then
            AktSong.BPM[0].BPM := AktSong.BPM[0].BPM + 4; // (1/1)
          if SDL_ModState = KMOD_LCTRL then
            AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) + 1) / 25; // (1/100)
        end;

      SDLK_MINUS:
        begin
          // Decrease BPM
          if SDL_ModState = 0 then
            AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) - 1) / 5;
          if SDL_ModState = KMOD_LSHIFT then
            AktSong.BPM[0].BPM := AktSong.BPM[0].BPM - 4;
          if SDL_ModState = KMOD_LCTRL then
            AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) - 1) / 25;
        end;

      SDLK_0:
        begin
          // Increase GAP
          if SDL_ModState = 0 then
            AktSong.GAP := AktSong.GAP + 10;
          if SDL_ModState = KMOD_LSHIFT then
            AktSong.GAP := AktSong.GAP + 1000;
        end;

      SDLK_9:
        begin
          // Decrease GAP
          if SDL_ModState = 0 then
            AktSong.GAP := AktSong.GAP - 10;
          if SDL_ModState = KMOD_LSHIFT then
            AktSong.GAP := AktSong.GAP - 1000;
        end;

      SDLK_KP_PLUS:
        begin
          // Increase tone of all notes
          if SDL_ModState = 0 then
            ChangeWholeTone(1);
          if SDL_ModState = KMOD_LSHIFT then
            ChangeWholeTone(12);
        end;

      SDLK_KP_MINUS:
        begin
          // Decrease tone of all notes
          if SDL_ModState = 0 then
            ChangeWholeTone(-1);
          if SDL_ModState = KMOD_LSHIFT then
            ChangeWholeTone(-12);
        end;

      SDLK_SLASH:
        begin
          if SDL_ModState = 0 then begin
            // Insert start of sentece
            if AktNuta > 0 then
              DivideSentence;
          end;

          if SDL_ModState = KMOD_LSHIFT then begin
            // Join next sentence with current
            if Czesci[0].Akt < Czesci[0].High  then
              JoinSentence;
          end;

          if SDL_ModState = KMOD_LCTRL then begin
            // divide note
            DivideNote;
          end;

        end;


      SDLK_S:
        begin
          //Medley MOD:
          if (MedleyNotes.isStart and MedleyNotes.isEnd) and
            (MedleyNotes.start.line < MedleyNotes.end_.line) then
          begin
            AktSong.Medley.Source := msTag;
            AktSong.Medley.StartBeat:=Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].Start;
            AktSong.Medley.EndBeat:=Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Start +
              Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Dlugosc;
            AktSong.Medley.FadeIn_time := DEFAULT_FADE_IN_TIME;
            AktSong.Medley.FadeOut_time := DEFAULT_FADE_OUT_TIME;
          end else begin
            AktSong.Medley.Source := msNone;
            AktSong.Medley.StartBeat:=0;
            AktSong.Medley.EndBeat:=0;
          end;

          // Save Song
          if SDL_ModState = KMOD_LSHIFT then
          begin
            if (AktSong.Medley.Source = msTag) then
            begin
              ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
              Exit;
            end;

            SResult := SaveSong(AktSong, Czesci[0], Path + FileName, true); //save with relative
          end else
            SResult := SaveSong(AktSong, Czesci[0], Path + FileName, false);

          if SResult then
          begin
            Text[TextDebug].Text := Language.Translate('INFO_FILE_SAVED');
            CatSongs.Song[SongIndex] := AktSong;
          end else
          begin
            ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED'));
          end;

          Exit;
        end;

      // set Medley tags
      SDLK_A:
        begin
          if AktSong.Relative then
          begin
            ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
            Exit;
          end;

          if SDL_ModState = KMOD_LSHIFT then //Medley End Note
          begin
            if MedleyNotes.isEnd then
            begin
              if (Czesci[0].Akt=MedleyNotes.end_.line) and (AktNuta=MedleyNotes.end_.note) then
              begin
                MedleyNotes.isEnd := false;
                Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := false;
              end else
              begin
                Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
                Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].IsMedley := false;
                MedleyNotes.end_.line := Czesci[0].Akt;
                MedleyNotes.end_.note := AktNuta;
              end;
            end else
            begin
              MedleyNotes.isEnd := true;
              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
              MedleyNotes.end_.line := Czesci[0].Akt;
              MedleyNotes.end_.note := AktNuta;
            end;
          end else
          begin        //Medley Start Note
            if MedleyNotes.isStart then
            begin
              if (Czesci[0].Akt=MedleyNotes.start.line) and (AktNuta=MedleyNotes.start.note) then
              begin
                MedleyNotes.isStart := false;
                Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := false;
              end else
              begin
                Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
                Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].IsMedley := false;
                MedleyNotes.start.line := Czesci[0].Akt;
                MedleyNotes.start.note := AktNuta;
              end;
            end else
            begin
              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
              MedleyNotes.isStart := true;
              MedleyNotes.start.line := Czesci[0].Akt;
              MedleyNotes.start.note := AktNuta;
            end;
          end;

          //show length of medley
          Text[TextDebug].Text := FormatFloat('MedleyLength: #0.00s', GetMedleyLength);
          Exit;
        end;

      // jump to Medley tags
      SDLK_J:
        begin
          if AktSong.Relative then
          begin
            ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
            Exit;
          end;

          if (SDL_ModState = KMOD_LSHIFT) and MedleyNotes.IsEnd then //Medley End Note
          begin
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
            PlaySentenceMidi := false;
            PlayOneNoteMidi := false;

            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Czesci[0].Akt := MedleyNotes.end_.line;
            AktNuta := MedleyNotes.end_.note;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;

            Lyric.AddCzesc(Czesci[0].Akt);
            Lyric.Selected := AktNuta;
            Music.Stop;
            PlaySentence := false;
            PlayOneNote := false;
          end else if MedleyNotes.IsStart then
          begin
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
            PlaySentenceMidi := false;
            PlayOneNoteMidi := false;

            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Czesci[0].Akt := MedleyNotes.start.line;
            AktNuta := MedleyNotes.start.note;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;

            Lyric.AddCzesc(Czesci[0].Akt);
            Lyric.Selected := AktNuta;
            Music.Stop;
            PlaySentence := false;
            PlayOneNote := false;
          end;

          if (SDL_ModState = KMOD_LALT) then
          begin
            PlaySentenceMidi := false;
            PlayOneNoteMidi := false;
            Music.Stop;
            LineChanged:=false;
            R := GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].Start);
            if R <= Music.Length then begin
              Music.MoveTo(R);
              PlayStopTime := GetTimeFromBeat(
                Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Start +
                Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Dlugosc);
              PlaySentence := true;
              PlayOneNote := false;
              Music.Play;
              LastClick := -100;
            end;
          end;

          //show length of medley
          Text[TextDebug].Text := FormatFloat('MedleyLength: #0.00s', GetMedleyLength);
          Exit;
        end;

      SDLK_K: //Preview Start
        begin
          if (SDL_ModState = KMOD_LSHIFT) then    //jump to...
          begin
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
            PlaySentenceMidi := false;
            PlayOneNoteMidi := false;

            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Czesci[0].Akt := MedleyNotes.Preview.line;
            AktNuta := MedleyNotes.Preview.note;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;

            Lyric.AddCzesc(Czesci[0].Akt);
            Lyric.Selected := AktNuta;
            Music.Stop;
            PlaySentence := false;
            PlayOneNote := false;
          end else
          begin
            if (Czesci[0].Akt = MedleyNotes.Preview.line) and (AktNuta = MedleyNotes.Preview.note) then //reset ?
            begin

            end else //set
            begin
              Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := false;
              MedleyNotes.Preview.line := Czesci[0].Akt;
              MedleyNotes.Preview.note := AktNuta;
              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsStartPreview := true;
              AktSong.PreviewStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].start);
            end;
          end;
        end;


      SDLK_D:
        begin
          // Divide lengths by 2
          CzesciDivide;
        end;

      SDLK_M:
        begin
          // Multiply lengths by 2
          CzesciMultiply;
        end;

      SDLK_C:
        begin
          // Capitalize letter at the beginning of line
          if SDL_ModState = 0 then
            LyricsCapitalize;

          // Correct spaces
          if SDL_ModState = KMOD_LSHIFT then
            LyricsCorrectSpaces;

          // Copy sentence
          if SDL_ModState = KMOD_LCTRL then
            MarkSrc;
        end;

      SDLK_R:   //reload
        begin
          onHide;
          onShow;
        end;

      SDLK_V:
        begin
          // Paste text
          if SDL_ModState = KMOD_LCTRL then begin
            if Czesci[0].Czesc[Czesci[0].Akt].IlNut >= Czesci[0].Czesc[CopySrc].IlNut then
              PasteText
            else
              beep;
          end;

          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
            CopySentence(CopySrc, Czesci[0].Akt);
          end;
        end;

      SDLK_4:
        begin
          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
            CopySentence(CopySrc, Czesci[0].Akt);
            CopySentence(CopySrc+1, Czesci[0].Akt+1);
            CopySentence(CopySrc+2, Czesci[0].Akt+2);
            CopySentence(CopySrc+3, Czesci[0].Akt+3);
          end;

          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
            CopySentences(CopySrc, Czesci[0].Akt, 4);
          end;
        end;
      SDLK_5:
        begin
          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
            CopySentence(CopySrc, Czesci[0].Akt);
            CopySentence(CopySrc+1, Czesci[0].Akt+1);
            CopySentence(CopySrc+2, Czesci[0].Akt+2);
            CopySentence(CopySrc+3, Czesci[0].Akt+3);
            CopySentence(CopySrc+4, Czesci[0].Akt+4);
          end;

          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
            CopySentences(CopySrc, Czesci[0].Akt, 5);
          end;
        end;

      SDLK_T:
        begin
          // Fixes timings between sentences
          FixTimings;
        end;

      SDLK_F4:
        begin
          // Enter Text Edit Mode
          editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
          TextEditMode := true;
        end;

      SDLK_F5:
        begin
          // Enter BPM Edit Mode
          Text[TextBPM].Text := Text[TextBPM].Text + '|';
          BPMEditMode := true;
        end;

      SDLK_P:
        begin
          if SDL_ModState = 0 then begin
            // Play Sentence
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
            PlaySentenceMidi := false;
            PlayOneNoteMidi := false;
            Click := true;
            Music.Stop;
            R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            if R <= Music.Length then begin
              Music.MoveTo(R);
              PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
              PlaySentence := true;
              PlayOneNote := false;
              Music.Play;
              LastClick := -100;
            end;
          end;

          if SDL_ModState = KMOD_LSHIFT then begin
            PlaySentenceMidi := true;
            PlayOneNoteMidi := false;
            MidiTime := USTime.GetTime;
            Music.Stop;
            PlaySentence := false;
            PlayOneNote := false;
            MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);

            LastClick := -100;
          end;

          if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
            PlaySentenceMidi := true;
            PlayOneNoteMidi := false;
            MidiTime := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
            LastClick := -100;

            PlaySentence := true;
            PlayOneNote := false;
            Click := true;
            Music.Stop;
            Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
            PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec)+0;
            Music.Play;
            LastClick := -100;
          end;

          //new: play hole file + LALT
          if SDL_ModState = KMOD_LALT then begin
            // Play Sentence
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
            PlaySentenceMidi := false;
            PlayOneNoteMidi := false;
            Click := true;
            Music.Stop;
            R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            if R <= Music.Length then begin
              Music.MoveTo(R);
              PlayStopTime := Music.Length;
              PlaySentence := true;
              PlayOneNote := false;
              Music.Play;
              LastClick := -100;
            end;
          end;

          if SDL_ModState = KMOD_LSHIFT or KMOD_LALT then begin
            PlaySentenceMidi := true;
            PlayOneNoteMidi := false;
            Music.Stop;
            PlaySentence := false;
            PlayOneNote := false;
            MidiTime := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            MidiStop := Music.Length;

            LastClick := -100;
          end;

          if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL or KMOD_LALT then begin
            PlaySentenceMidi := true;
            PlayOneNoteMidi := false;
            MidiTime := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            MidiStop := Music.Length;
            LastClick := -100;

            PlaySentence := true;
            PlayOneNote := false;
            Click := true;
            Music.Stop;
            Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
            PlayStopTime := Music.Length;
            Music.Play;
            LastClick := -100;
          end;

          if PlaySentenceMidi or PlaySentence then
          begin
            noteStart := AktNuta;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            AktNuta := 0;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
            Lyric.Selected := AktNuta;
            LineChanged:=false;
          end;

        end;

      SDLK_SPACE:
        begin
          //Thx to f1fth_freed0m for his One Note Midi Playback
          if SDL_ModState = KMOD_LSHIFT then begin //Play One Notes Midi [Shift + Space]
            PlaySentenceMidi := false;
            PlayOneNoteMidi := true;
            Music.Stop;
            PlaySentence := false;
            PlayOneNote := false;
            MidiTime := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
            MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
            LastClick := -100;
          end

          else if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
            //Play One Notes Midi + MP3 [CTRL + Shift + Space]
            PlaySentenceMidi := false;
            PlayOneNoteMidi := true;
            MidiTime := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
            MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
            LastClick := -100;

            PlaySentence := false;
            PlayOneNote := true;
            Click := true;
            Music.Stop;
            Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
            PlayStopTime := (GetTimeFromBeat(
                             Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
                             Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
            Music.Play;
            LastClick := -100;
          end

          Else
          begin
            // Play One Notes MP3 [Space]
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
            PlaySentenceMidi := false; // stop midi
            PlayOneNoteMidi := false;
            PlaySentence := false;
            PlayOneNote := true;
            Click := false;
            Music.Stop;

            Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
            PlayStopTime := (GetTimeFromBeat(
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
            Music.Play;
            LastClick := -100;
          end;


          if PlaySentence or PlaySentenceMidi then
          begin
            noteStart := AktNuta;
            LineChanged:=false;
          end;
        end;
      SDLK_RETURN:
        begin
        end;

      SDLK_LCTRL:
        begin
        end;

      SDLK_DELETE:
        begin
          if SDL_ModState = KMOD_LCTRL then begin
            // moves text to right in current sentence
            DeleteNote;
          end;
        end;

      SDLK_PERIOD:
        begin
          // moves text to right in current sentence
          MoveTextToRight;
        end;

      SDLK_RIGHT:
        begin
          if PlaySentenceMidi or PlaySentence then
          begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            AktNuta := noteStart;
            Dec(AktNuta);
            if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
            Lyric.Selected := AktNuta;
          end;
          MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
          PlaySentenceMidi := false;
          PlayOneNoteMidi := false;
          Music.Stop;
          LineChanged:=false;
          PlaySentence := false;
          PlayOneNote := false;

          // right
          if SDL_ModState = 0 then begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Inc(AktNuta);
            if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
            Lyric.Selected := AktNuta;
          end;

          // ctrl + right
          if SDL_ModState = KMOD_LCTRL then begin
            if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
              Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
              Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
              if AktNuta = 0 then begin
                Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
                Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
              end;
              FixTimings;
            end;
          end;

          // shift + right
          if SDL_ModState = KMOD_LSHIFT then begin
            Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
            if AktNuta = 0 then begin
              Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
              Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            end;
            if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
              Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
            FixTimings;
          end;

          // alt + right
          if SDL_ModState = KMOD_LALT then begin
            Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
            if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
              Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
            FixTimings;
          end;

          // alt + ctrl + shift + right = move all from cursor to right
          if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
            MoveAllToEnd(1);
            FixTimings;
          end;
        end;

      SDLK_LEFT:
        begin
          if PlaySentenceMidi or PlaySentence then
          begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            AktNuta := noteStart;
            Inc(AktNuta);
            if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
            Lyric.Selected := AktNuta;
          end;
          MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
          PlaySentenceMidi := false;
          PlayOneNoteMidi := false;
          Music.Stop;
          LineChanged:=false;
          PlaySentence := false;
          PlayOneNote := false;

          // left
          if SDL_ModState = 0 then begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Dec(AktNuta);
            if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
            Lyric.Selected := AktNuta;
          end;

          // ctrl + left
          if SDL_ModState = KMOD_LCTRL then begin
            Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
            Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
            if AktNuta = 0 then begin
              Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
              Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            end;
            FixTimings;
          end;

          // shift + left
          if SDL_ModState = KMOD_LSHIFT then begin
            Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);

            // resizing sentences
            if AktNuta = 0 then begin
              Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
              Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
            end;

            if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
              Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
            FixTimings;
          end;

          // alt + left
          if SDL_ModState = KMOD_LALT then begin
            if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
              Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
              if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
                Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
            end;
            FixTimings;
          end;

          // alt + ctrl + shift + right = move all from cursor to left
          if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
            MoveAllToEnd(-1);
            FixTimings;
          end;
        end;

      SDLK_DOWN:
        begin
          MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
          PlaySentenceMidi := false;
          PlayOneNoteMidi := false;
          Music.Stop;
          LineChanged:=false;
          PlaySentence := false;
          PlayOneNote := false;

          // skip to next sentence
          if SDL_ModState = 0 then begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Inc(Czesci[0].Akt);
            AktNuta := 0;
            if Czesci[0].Akt > Czesci[0].High then
              Czesci[0].Akt := 0;

            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;

            Lyric.AddCzesc(Czesci[0].Akt);
            Lyric.Selected := 0;
          end;

          // decrease tone
          if SDL_ModState = KMOD_LCTRL then begin
            TransposeNote(-1);
          end;

        end;

      SDLK_UP:
        begin
          MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
          PlaySentenceMidi := false;
          PlayOneNoteMidi := false;
          Music.Stop;
          LineChanged:=false;
          PlaySentence := false;
          PlayOneNote := false;

          // skip to previous sentence
          if SDL_ModState = 0 then begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Dec(Czesci[0].Akt);
            AktNuta := 0;
            if Czesci[0].Akt = -1 then
              Czesci[0].Akt := Czesci[0].High;

            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;

            Lyric.AddCzesc(Czesci[0].Akt);
            Lyric.Selected := 0;
          end;

          // increase tone
          if SDL_ModState = KMOD_LCTRL then begin
            TransposeNote(1);
          end;
        end;

      // Golden Note Patch
      SDLK_G:
        begin
          case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
            0, 1: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 2;
            2:    Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
          end; // case
          Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
        end;

      // Freestyle Note Patch
      SDLK_F:
        begin
           case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
            0:
            begin;
              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
            end;
            1,2:
            begin;
              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 0;
              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := True;
            end;
          end; // case

        end;

      //MP3-Volume Up
      SDLK_PAGEUP:
        begin
          if (MP3Volume<100) then
            MP3Volume := MP3Volume+5;
            Music.SetMusicVolume(MP3Volume);
            Text[TextDebug].Text := 'MP3 Volume: ' + IntToStr(MP3Volume) + '%';
        end;

      //MP3-Volume Down
      SDLK_PAGEDOWN:
        begin
          if (MP3Volume>0) then
            MP3Volume := MP3Volume-5;
            Music.SetMusicVolume(MP3Volume);
            Text[TextDebug].Text := 'MP3 Volume: ' + IntToStr(MP3Volume) + '%';
        end;

      end;
    end;
  end; // if
end;

function TScreenEditSub.ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
  SDL_ModState:  Word;
begin
  // used when in Text Edit Mode
  Result := true;

  SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
    + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT  + KMOD_RALT {+ KMOD_CAPS});

  if Ini.Debug=1 then
    Text[TextDebug].Text := 'PressedKey: ' + IntToStr(PressedKey) + ' ScanCode: ' + IntToStr(ScanCode);

  // check normal keys
    if not (ScanCode in [0..31, 127..159]) then //=isPrintable
    begin
      Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst :=
      Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst + chr(ScanCode);

      Lyric.ChangeCurText(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst);
      Lyric.AddCzesc(Czesci[0].Akt);
      Exit;
    end;

  If (PressedDown) Then
  begin // Key Down
    case PressedKey of
      SDLK_ESCAPE:
        begin
          Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst := editText;
          Lyric.AddCzesc(Czesci[0].Akt);
          TextEditMode := false;
        end;
      SDLK_F4, SDLK_RETURN:
        begin
          // Exit Text Edit Mode
          TextEditMode := false;
        end;
      
      SDLK_BACKSPACE:
        begin
          Delete(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst,
            Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst), 1);

          Lyric.ChangeCurText(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst);
          Lyric.AddCzesc(Czesci[0].Akt);
        end;
      SDLK_RIGHT:
        begin
          // right
          if SDL_ModState = 0 then begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Inc(AktNuta);
            if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
            Lyric.Selected := AktNuta;
            editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
          end;
        end;
      SDLK_LEFT:
        begin
          // left
          if SDL_ModState = 0 then begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            Dec(AktNuta);
            if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
            Lyric.Selected := AktNuta;
            editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
          end;
      end;
    end;
  end;
end;

function TScreenEditSub.ParseInputEditBPM(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
  SDL_ModState: Word;
  strBPM:       string;
  temp:         real;

begin
  // used when in Text Edit Mode
  Result := true;

  SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
    + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT  + KMOD_RALT {+ KMOD_CAPS});

  // check normal keys
  if (ScanCode in [48..57, 44]) then
  begin
    strBPM := Text[TextBPM].Text;
    Delete(strBPM, Length(strBPM), 1);
    Text[TextBPM].Text := strBPM + chr(ScanCode) + '|';
    Exit;
  end;

  If (PressedDown) Then
  begin // Key Down
    case PressedKey of
      SDLK_ESCAPE:
        begin
          Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);
          BPMEditMode := false;
        end;
      SDLK_F5, SDLK_RETURN:
        begin
          strBPM := Text[TextBPM].Text;
          Delete(strBPM, Length(strBPM), 1);
          Temp := StrToFloatDef(strBPM, 0);
          if (temp>0) then
            ChangeBPM(temp*4);

          BPMEditMode := false;
        end;
      
      SDLK_BACKSPACE:
        begin
          strBPM := Text[TextBPM].Text;
          Delete(strBPM, Length(strBPM)-1, 2);
          Text[TextBPM].Text := strBPM + '|';
        end;
    end;
  end;
end;

procedure TScreenEditSub.NewBeat;
begin
    // click
{    for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
  if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin
      // old}
//    Music.PlayClick;
end;

procedure TScreenEditSub.ChangeBPM(newBPM: real);
var
  C:    integer;
  N:    integer;
  f:    real;

begin                    
  f := newBPM/AktSong.BPM[0].BPM;    //z.B. neu/alt => 1/2 = 0.5 => *0.5
  AktSong.BPM[0].BPM := newBPM;

  for C := 0 to Czesci[0].High do
  begin
    Czesci[0].Czesc[C].Start :=    ceil(Czesci[0].Czesc[C].Start *f);
    Czesci[0].Czesc[C].StartNote := ceil(Czesci[0].Czesc[C].StartNote *f);
    for N := 0 to Czesci[0].Czesc[C].HighNut do
    begin
      Czesci[0].Czesc[C].Nuta[N].Start :=   ceil(Czesci[0].Czesc[C].Nuta[N].Start *f);
      Czesci[0].Czesc[C].Nuta[N].Dlugosc := floor(Czesci[0].Czesc[C].Nuta[N].Dlugosc *f);
    end; // N (notes)
    Czesci[0].Czesc[C].Koniec :=    Czesci[0].Czesc[C].Nuta[Czesci[0].Czesc[C].HighNut].Start +
      Czesci[0].Czesc[C].Nuta[Czesci[0].Czesc[C].HighNut].Dlugosc;
  end; // C (lines)
end;


procedure TScreenEditSub.CzesciDivide;
var
  C:    integer;
  N:    integer;
begin                    
  AktSong.BPM[0].BPM := AktSong.BPM[0].BPM / 2;
  for C := 0 to Czesci[0].High do begin
    Czesci[0].Czesc[C].Start :=     Czesci[0].Czesc[C].Start div 2;
    Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote div 2;
    Czesci[0].Czesc[C].Koniec :=    Czesci[0].Czesc[C].Koniec div 2;
    for N := 0 to Czesci[0].Czesc[C].HighNut do begin
      Czesci[0].Czesc[C].Nuta[N].Start :=   Czesci[0].Czesc[C].Nuta[N].Start div 2;
      Czesci[0].Czesc[C].Nuta[N].Dlugosc := Round(Czesci[0].Czesc[C].Nuta[N].Dlugosc / 2);
    end; // N
  end; // C
end;

procedure TScreenEditSub.CzesciMultiply;
var
  C:    integer;
  N:    integer;
begin
  AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2;
  for C := 0 to Czesci[0].High do begin
    Czesci[0].Czesc[C].Start :=     Czesci[0].Czesc[C].Start * 2;
    Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote * 2;
    Czesci[0].Czesc[C].Koniec :=    Czesci[0].Czesc[C].Koniec * 2;
    for N := 0 to Czesci[0].Czesc[C].HighNut do begin
      Czesci[0].Czesc[C].Nuta[N].Start :=   Czesci[0].Czesc[C].Nuta[N].Start * 2;
      Czesci[0].Czesc[C].Nuta[N].Dlugosc := Czesci[0].Czesc[C].Nuta[N].Dlugosc * 2;
    end; // N
  end; // C
end;

procedure TScreenEditSub.LyricsCapitalize;
var
  C:    integer;
  N:    integer; // temporary
  S:    string;
begin
  // temporary
{  for C := 0 to Czesci[0].High do
    for N := 0 to Czesci[0].Czesc[C].HighNut do
      Czesci[0].Czesc[C].Nuta[N].Tekst := AnsiLowerCase(Czesci[0].Czesc[C].Nuta[N].Tekst);}

  for C := 0 to Czesci[0].High do begin
    S := AnsiUpperCase(Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1));
    S := S + Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, Length(Czesci[0].Czesc[C].Nuta[0].Tekst)-1);
    Czesci[0].Czesc[C].Nuta[0].Tekst := S;
  end; // C
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.LyricsCorrectSpaces;
var
  C:    integer;
  N:    integer;
begin
  for C := 0 to Czesci[0].High do begin
    // correct starting spaces in the first word
    while Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1) = ' ' do
      Czesci[0].Czesc[C].Nuta[0].Tekst := Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, 100);

    // move spaces on the start to the end of the previous note
    for N := 1 to Czesci[0].Czesc[C].HighNut do begin
      while (Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, 1) = ' ') do begin
        Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 2, 100);
        Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
      end;
    end; // N

    // correct '-'  to '- '
    for N := 0 to Czesci[0].Czesc[C].HighNut do begin
      if Czesci[0].Czesc[C].Nuta[N].Tekst = '-' then
        Czesci[0].Czesc[C].Nuta[N].Tekst := '- ';
    end; // N

    // add space to the previous note when the current word is '- '
    for N := 1 to Czesci[0].Czesc[C].HighNut do begin
      if Czesci[0].Czesc[C].Nuta[N].Tekst  = '- ' then
        Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
    end; // N

    // correct too many spaces at the end of note
    for N := 0 to Czesci[0].Czesc[C].HighNut do begin
      while Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1, 2) = '  ' do
        Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1);
    end; // N

    // and correct if there is no space at the end of sentence
    N := Czesci[0].Czesc[C].HighNut;
    if Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst), 1) <> ' ' then
      Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N].Tekst + ' ';

  end; // C
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.FixTimings;
var
  C:    integer;
  S:    integer;
  Min:  integer;
  Max:  integer;
begin
  for C := 1 to Czesci[0].High do begin
    with Czesci[0].Czesc[C-1] do begin
      Min := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
      Max := Czesci[0].Czesc[C].StartNote;
      case (Max - Min) of
        0:    S := Max;
        1:    S := Max;
        2:    S := Max - 1;
        3:    S := Max - 2;
        else
          S := Min + 2;

      end; // case

      Czesci[0].Czesc[C].Start := S;
    end; // with
  end; // for
end;

procedure TScreenEditSub.DivideSentence;
var
  C:      integer;
  CStart: integer;
  CNew:   integer;
  CLen:   integer;
  N:      integer;
  NStart: integer;
  NHigh:  integer;
  NNewL:  integer;
begin
  // increase sentence length by 1
  CLen := Length(Czesci[0].Czesc);
  SetLength(Czesci[0].Czesc, CLen + 1);
  Inc(Czesci[0].Ilosc);
  Inc(Czesci[0].High);

  // move needed sentences to one forward. newly has the copy of divided sentence
  CStart := Czesci[0].Akt;
  for C := CLen-1 downto CStart do
    Czesci[0].Czesc[C+1] := Czesci[0].Czesc[C];

  // clear and set new sentence
  CNew := CStart + 1;
  NStart := AktNuta;
  Czesci[0].Czesc[CNew].Start := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
  Czesci[0].Czesc[CNew].StartNote := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
  Czesci[0].Czesc[CNew].Lyric := '';
  Czesci[0].Czesc[CNew].LyricWidth := 0;
  Czesci[0].Czesc[CNew].Koniec := 0;
  Czesci[0].Czesc[CNew].BaseNote := 0; // 0.5.0: we modify it later in this procedure
  Czesci[0].Czesc[CNew].IlNut := 0;
  Czesci[0].Czesc[CNew].HighNut := -1;
  SetLength(Czesci[0].Czesc[CNew].Nuta, 0);

  // move right notes to new sentences
  NHigh := Czesci[0].Czesc[CStart].HighNut;
  for N := NStart to NHigh do begin
    NNewL := Czesci[0].Czesc[CNew].IlNut;
    SetLength(Czesci[0].Czesc[CNew].Nuta, NNewL + 1);
    Czesci[0].Czesc[CNew].Nuta[NNewL] := Czesci[0].Czesc[CStart].Nuta[N];

    // increase sentence counters
    Inc(Czesci[0].Czesc[CNew].IlNut);
    Inc(Czesci[0].Czesc[CNew].HighNut);
    Czesci[0].Czesc[CNew].Koniec := Czesci[0].Czesc[CNew].Nuta[NNewL].Start +
      Czesci[0].Czesc[CNew].Nuta[NNewL].Dlugosc;
  end;

  // clear old notes and set sentence counters
  Czesci[0].Czesc[CStart].HighNut := NStart - 1;
  Czesci[0].Czesc[CStart].IlNut := Czesci[0].Czesc[CStart].HighNut + 1;
  Czesci[0].Czesc[CStart].Koniec := Czesci[0].Czesc[CStart].Nuta[NStart-1].Start +
    Czesci[0].Czesc[CStart].Nuta[NStart-1].Dlugosc;
  SetLength(Czesci[0].Czesc[CStart].Nuta, Czesci[0].Czesc[CStart].IlNut);

  // 0.5.0: modify BaseNote
  Czesci[0].Czesc[CNew].BaseNote := 120;
  for N := 0 to Czesci[0].Czesc[CNew].IlNut do
    if Czesci[0].Czesc[CNew].Nuta[N].Ton < Czesci[0].Czesc[CNew].BaseNote then
      Czesci[0].Czesc[CNew].BaseNote := Czesci[0].Czesc[CNew].Nuta[N].Ton;

  Czesci[0].Akt := Czesci[0].Akt + 1;
  AktNuta := 0;
  Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
  Lyric.AddCzesc(Czesci[0].Akt);

end;

procedure TScreenEditSub.JoinSentence;
var
  C:      integer;
  N:      integer;
  NStart: integer;
  NDst:   integer;
begin
  C := Czesci[0].Akt;

  // set new sentence
  NStart := Czesci[0].Czesc[C].IlNut;
  Czesci[0].Czesc[C].IlNut := Czesci[0].Czesc[C].IlNut + Czesci[0].Czesc[C+1].IlNut;
  Czesci[0].Czesc[C].HighNut := Czesci[0].Czesc[C].HighNut + Czesci[0].Czesc[C+1].IlNut;
  SetLength(Czesci[0].Czesc[C].Nuta, Czesci[0].Czesc[C].IlNut);

  // move right notes to new sentences
  for N := 0 to Czesci[0].Czesc[C+1].HighNut do begin
    NDst := NStart + N;
    Czesci[0].Czesc[C].Nuta[NDst] := Czesci[0].Czesc[C+1].Nuta[N];
  end;

  // increase sentence counters
  NDst := Czesci[0].Czesc[C].HighNut;
  Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Nuta[NDst].Start +
    Czesci[0].Czesc[C].Nuta[NDst].Dlugosc;

  // move needed sentences to one backward.
  for C := Czesci[0].Akt + 1 to Czesci[0].High - 1 do
    Czesci[0].Czesc[C] := Czesci[0].Czesc[C+1];

  // increase sentence length by 1
  SetLength(Czesci[0].Czesc, Length(Czesci[0].Czesc) - 1);
  Dec(Czesci[0].Ilosc);
  Dec(Czesci[0].High);
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.DivideNote;
var
  C:    integer;
  N:    integer;
  NLen: integer;
begin
  C := Czesci[0].Akt;

  NLen := Czesci[0].Czesc[C].IlNut + 1;
  SetLength(Czesci[0].Czesc[C].Nuta, NLen);
  Inc(Czesci[0].Czesc[C].HighNut);
  Inc(Czesci[0].Czesc[C].IlNut);

  // we copy all notes including selected one
  for N := Czesci[0].Czesc[C].HighNut downto AktNuta+1 do begin
    Czesci[0].Czesc[C].Nuta[N] := Czesci[0].Czesc[C].Nuta[N-1];
  end;

  // me slightly modify new note
  Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc := ceil(Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc/2);

  Czesci[0].Czesc[C].Nuta[AktNuta+1].Start := Czesci[0].Czesc[C].Nuta[AktNuta+1].Start +
    Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc;

  Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc := Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc -
    Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc;

  if (Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc>0) then
    Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := '~ '
  else
    Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := ' ';

  Czesci[0].Czesc[C].Nuta[AktNuta].Color := 0;
  Czesci[0].Czesc[C].Nuta[AktNuta+1].Color := 2;

  Inc(AktNuta);
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.DeleteNote;
var
  C:    integer;
  N:    integer;
  NLen: integer;
begin
  C := Czesci[0].Akt;

  //Do Not delete Last Note
  if (Czesci[0].High > 0) OR (Czesci[0].Czesc[C].HighNut > 0) then
  begin

    // we copy all notes from the next to the selected one
    for N := AktNuta+1 to Czesci[0].Czesc[C].HighNut do begin
      Czesci[0].Czesc[C].Nuta[N-1] := Czesci[0].Czesc[C].Nuta[N];
    end;

    NLen := Czesci[0].Czesc[C].IlNut - 1;

    if (NLen > 0) then
    begin
      SetLength(Czesci[0].Czesc[C].Nuta, NLen);
      Dec(Czesci[0].Czesc[C].HighNut);
      Dec(Czesci[0].Czesc[C].IlNut);


      // me slightly modify new note
      if AktNuta > Czesci[0].Czesc[C].HighNut then Dec(AktNuta);
        Czesci[0].Czesc[C].Nuta[AktNuta].Color := 2;
    end
    //Last Note of current Sentence Deleted - > Delete Sentence
    else
    begin
      //Move all Sentences after the current to the Left
      for N := C+1 to Czesci[0].High do
        Czesci[0].Czesc[N-1] := Czesci[0].Czesc[N];

      //Delete Last Sentence
      SetLength(Czesci[0].Czesc, Czesci[0].High);
      Czesci[0].High := High(Czesci[0].Czesc);
      Czesci[0].Ilosc := Length(Czesci[0].Czesc);

      AktNuta := 0;
      if (C > 0) then
        Czesci[0].Akt := C - 1
      else
        Czesci[0].Akt := 0;

      Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
    end;
  end;
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.TransposeNote(Transpose: integer);
begin
  Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton, Transpose);
end;

procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
var
  C:  integer;
  N:  integer;
begin
  for C := 0 to Czesci[0].High do begin
    Czesci[0].Czesc[C].BaseNote := Czesci[0].Czesc[C].BaseNote + Tone;
    for N := 0 to Czesci[0].Czesc[C].HighNut do
      Czesci[0].Czesc[C].Nuta[N].Ton := Czesci[0].Czesc[C].Nuta[N].Ton + Tone;
  end;
end;

procedure TScreenEditSub.MoveAllToEnd(Move: integer);
var
  C:    integer;
  N:    integer;
  NStart: integer;
begin
  for C := Czesci[0].Akt to Czesci[0].High do begin
    NStart := 0;
    if C = Czesci[0].Akt then NStart := AktNuta;
    for N := NStart to Czesci[0].Czesc[C].HighNut do begin
      Inc(Czesci[0].Czesc[C].Nuta[N].Start, Move); // move note start

      if N = 0 then begin // fix beginning
        Inc(Czesci[0].Czesc[C].Start, Move);
        Inc(Czesci[0].Czesc[C].StartNote, Move);
      end;

      if N = Czesci[0].Czesc[C].HighNut then // fix ending
        Inc(Czesci[0].Czesc[C].Koniec, Move);

    end; // for
  end; // for
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.MoveTextToRight;
var
  C:      integer;
  N:      integer;
  NHigh:  integer;
begin
{  C := Czesci[0].Akt;

  for N := Czesci[0].Czesc[C].HighNut downto 1 do begin
    Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
  end; // for

  Czesci[0].Czesc[C].Nuta[0].Tekst := '- ';}

  C := Czesci[0].Akt;
  NHigh := Czesci[0].Czesc[C].HighNut;

  // last word
  Czesci[0].Czesc[C].Nuta[NHigh].Tekst := Czesci[0].Czesc[C].Nuta[NHigh-1].Tekst + Czesci[0].Czesc[C].Nuta[NHigh].Tekst;

  // other words
  for N := NHigh - 1 downto AktNuta + 1 do begin
    Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
  end; // for
  Czesci[0].Czesc[C].Nuta[AktNuta].Tekst := '- ';
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.MarkSrc;
begin
  CopySrc := Czesci[0].Akt;
end;

procedure TScreenEditSub.PasteText;
var
  C:    integer;
  N:    integer;
begin
  C := Czesci[0].Akt;

  for N := 0 to Czesci[0].Czesc[CopySrc].HighNut do
    Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[CopySrc].Nuta[N].Tekst;
  Lyric.AddCzesc(Czesci[0].Akt);
end;

procedure TScreenEditSub.CopySentence(Src, Dst: integer);
var
  N:      integer;
  Time1:  integer;
  Time2:  integer;
  TD:  integer;
begin
  Time1 := Czesci[0].Czesc[Src].Nuta[0].Start;
  Time2 := Czesci[0].Czesc[Dst].Nuta[0].Start;
  TD := Time2-Time1;

  SetLength(Czesci[0].Czesc[Dst].Nuta, Czesci[0].Czesc[Src].IlNut);
  Czesci[0].Czesc[Dst].IlNut := Czesci[0].Czesc[Src].IlNut;
  Czesci[0].Czesc[Dst].HighNut := Czesci[0].Czesc[Src].HighNut;
  for N := 0 to Czesci[0].Czesc[Src].HighNut do begin
    Czesci[0].Czesc[Dst].Nuta[N].Tekst := Czesci[0].Czesc[Src].Nuta[N].Tekst;
    Czesci[0].Czesc[Dst].Nuta[N].Dlugosc := Czesci[0].Czesc[Src].Nuta[N].Dlugosc;
    Czesci[0].Czesc[Dst].Nuta[N].Ton := Czesci[0].Czesc[Src].Nuta[N].Ton;
    Czesci[0].Czesc[Dst].Nuta[N].Start := Czesci[0].Czesc[Src].Nuta[N].Start + TD;
  end;
  N := Czesci[0].Czesc[Src].HighNut;
  Czesci[0].Czesc[Dst].Koniec := Czesci[0].Czesc[Dst].Nuta[N].Start + Czesci[0].Czesc[Dst].Nuta[N].Dlugosc;
end;

procedure TScreenEditSub.CopySentences(Src, Dst, Num: integer);
var
  C:      integer;
begin
  // create place for new sentences
  SetLength(Czesci[0].Czesc, Czesci[0].Ilosc + Num - 1);

  // moves sentences next to the destination
  for C := Czesci[0].High downto Dst + 1 do begin
    Czesci[0].Czesc[C + Num - 1] := Czesci[0].Czesc[C];
  end;

  // prepares new sentences: sets sentence start and create first note
  for C := 1 to Num-1 do begin
    Czesci[0].Czesc[Dst + C].Start := Czesci[0].Czesc[Dst + C - 1].StartNote +
      (Czesci[0].Czesc[Src + C].StartNote - Czesci[0].Czesc[Src + C - 1].StartNote);
    SetLength(Czesci[0].Czesc[Dst + C].Nuta, 1);
    Czesci[0].Czesc[Dst + C].IlNut := 1;
    Czesci[0].Czesc[Dst + C].HighNut := 0;
    Czesci[0].Czesc[Dst + C].Nuta[0].Start := Czesci[0].Czesc[Dst + C].Start;
    Czesci[0].Czesc[Dst + C].Nuta[0].Dlugosc := 1;
    Czesci[0].Czesc[Dst + C].StartNote := Czesci[0].Czesc[Dst + C].Start;
    Czesci[0].Czesc[Dst + C].Koniec := Czesci[0].Czesc[Dst + C].Start + 1;
  end;

  // increase counters
  Czesci[0].Ilosc := Czesci[0].Ilosc + Num - 1;
  Czesci[0].High := Czesci[0].High + Num - 1;

  for C := 0 to Num-1 do
    CopySentence(Src + C, Dst + C);
end;


constructor TScreenEditSub.Create;
begin
  inherited Create;
  SetLength(Player, 1);

  //Theme:
  //bg
  AddStatic(0, 0, 800, 600, 0.3, 0.5, 0.6, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');

  // Line
  AddStatic(20, 5, 200, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
  AddText(40, 14, 1, 8, 0, 0, 0, 'Line:');
  TextSentence := AddText(110, 14, 1, 8, 0, 0, 0, '0 / 0');

  // Note
  AddStatic(260, 5, 200, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
  AddText(282, 14, 1, 8, 0, 0, 0, 'Note:');
  TextNote := AddText(360, 14, 1, 8, 0, 0, 0, '0 / 0');

  // some borders
  AddStatic(18, 53, 764, 240, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
  AddStatic(20, 55, 760, 236, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');

  AddStatic(18, 303, 764, 139, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
  AddStatic(20, 305, 760, 135, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');

  AddStatic(18, 498, 764, 44, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
  AddStatic(20, 500, 760, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');


  AddText(30, 65,  0, 8, 0, 0, 0, 'Title:');
  AddText(30, 90,  0, 8, 0, 0, 0, 'Artist:');
  AddText(30, 115, 0, 8, 0, 0, 0, 'Mp3:');
  AddText(30, 140, 0, 8, 0, 0, 0, 'BPM:');
  AddText(30, 165, 0, 8, 0, 0, 0, 'GAP:');

  TextTitle :=  AddText(180, 65,  0, 8, 0, 0, 0, 'a');
  TextArtist := AddText(180, 90,  0, 8, 0, 0, 0, 'b');
  TextMp3 :=    AddText(180, 115, 0, 8, 0, 0, 0, 'c');
  TextBPM :=    AddText(180, 140, 0, 8, 0, 0, 0, 'd');
  TextGAP :=    AddText(180, 165, 0, 8, 0, 0, 0, 'e');

{  AddInteraction(2, TextTitle);
  AddInteraction(2, TextArtist);
  AddInteraction(2, TextMp3);
  AddInteraction(2, TextBPM);
  AddInteraction(2, TextGAP);}

  // note info
  AddText(30, 190,  0, 8, 0, 0, 0, 'Start:');
  AddText(30, 215,  0, 8, 0, 0, 0, 'Duration:');
  AddText(30, 240,  0, 8, 0, 0, 0, 'Tone:');
  AddText(30, 265,  0, 8, 0, 0, 0, 'Text:');

  TextNStart :=   AddText(180, 190,  0, 8, 0, 0, 0, 'a');
  TextNDlugosc := AddText(180, 215,  0, 8, 0, 0, 0, 'b');
  TextNTon :=     AddText(180, 240,  0, 8, 0, 0, 0, 'c');
  TextNText :=    AddText(180, 265,  0, 8, 0, 0, 0, 'd');

  // debug
  TextDebug :=  AddText(30, 550, 0, 9, 0, 0, 0, '');
end;

procedure TScreenEditSub.onShow;
begin
  Log.LogStatus('Initializing', 'TEditScreen.onShow');

  try
    ResetSingTemp;
    AktSong := CatSongs.Song[SongIndex];
    Error := not LoadSong(Path + FileName, SONG_LOAD_COMPLETE);
    if not Error then
      FindRefrainStart(AktSong);
  except
    Error := True;
  end;

  if Error then
  begin
    //Error Loading Song -> Go back to Song Screen and Show some Error Message
    FadeTo(@ScreenSong);
    ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
    Exit;
  end
  else begin
    MidiOut := TMidiOutput.Create(nil);
    MidiOut.Open;

    //Set Volume
    MP3Volume := 50;
    Music.SetVolume(MP3Volume);

    if not Help.SetHelpID(ID) then
      Log.LogError('No Entry for Help-ID ' + ID + ' (ScreenEditSub)');

    Text[TextTitle].Text :=   AktSong.Title;
    Text[TextArtist].Text :=  AktSong.Artist;
    Text[TextMp3].Text :=     AktSong.Mp3;

    Czesci[0].Akt := 0;
    AktNuta := 0;
    noteStart := 0; //when playing sentence
    Czesci[0].Czesc[0].Nuta[0].Color := 2;

    if AktSong.Medley.Source <> msNone then
    begin
      MedleyNotes.isStart := true;
      MedleyNotes.isEnd := true;
      MedleyNotes.start := FindNote(AktSong.Medley.StartBeat);
      MedleyNotes.end_ := FindNote(AktSong.Medley.EndBeat);
      Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].IsMedley := true;
      Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].IsMedley := true;
    end;

    //set Preview Start
    MedleyNotes.Preview := FindNote(round(GetMidBeat(AktSong.PreviewStart-AktSong.Gap/1000)));
    Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := true;
    AktSong.PreviewStart := GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].start);

    Music.Open(Path + AktSong.Mp3);
    //Set Down Music Volume for Better hearability of Midi Sounds
    //Music.SetVolume(40);
    
    Lyric.Clear;
    Lyric.X := 400;
    Lyric.Y := 500;
    Lyric.Align := 1;
    Lyric.Size := 14;
    Lyric.ColR := 0;
    Lyric.ColG := 0;
    Lyric.ColB := 0;
    Lyric.ColSR := Skin_FontHighlightR;
    Lyric.ColSG := Skin_FontHighlightG;
    Lyric.ColSB := Skin_FontHighlightB;
    Lyric.Style := 0;
    Lyric.AddCzesc(0);
    Lyric.Selected := 0;

    NotesH := 7;
    NotesW := 4;

  end;

//  Interaction := 0;
  TextEditMode := false;
  BPMEditMode := false;

  MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
  PlaySentenceMidi := false;
  PlayOneNoteMidi := false;
  Music.Stop;
  LineChanged:=false;
  PlaySentence := false;
  PlayOneNote := false;
end;

function TScreenEditSub.Draw: boolean;
var
  Min:    integer;
  Sec:    integer;
  Tekst:  string;
  Pet:    integer;
  AktBeat:  integer;
  PlayClick:  boolean;
  line, note: integer;
  end_:   boolean;
begin
  glClearColor(1,1,1,1);

  PlayClick := false;
  if PlaySentenceMidi or PlaySentence then
  begin
    MidiPos := USTime.GetTime - MidiTime + MidiStart;
    // click
    if PlaySentence then
    begin
      AktBeat := Floor(GetMidBeat(Music.Position - AktSong.GAP / 1000));
      if Music.Position>PlayStopTime then
        end_ := true
      else
        end_ := false;
    end else
    begin
      AktBeat := Floor(GetMidBeat(MidiPos - AktSong.GAP / 1000));
      if MidiPos>MidiStop then
        end_ := true
      else
        end_ := false;
    end;

    if AktBeat <> LastClick then
    begin
      for line := 0 to Length(Czesci[0].Czesc) - 1 do
      begin
        for note := 0 to Length(Czesci[0].Czesc[line].Nuta) - 1 do
        begin
          //line change
          if (Czesci[0].Czesc[line].Start = AktBeat) and (line <> Czesci[0].Akt) and not end_ then
          begin
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
            AktNuta := 0;
            Inc(Czesci[0].Akt);
            if Czesci[0].Akt > Length(Czesci[0].Czesc)-1 then //useful?
              Czesci[0].Akt := 0;
            Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
            Lyric.AddCzesc(Czesci[0].Akt);
            Lyric.Selected := AktNuta;
            LineChanged := true;
          end;

          if (Czesci[0].Czesc[line].Nuta[note].Start = AktBeat) then
          begin
            LastClick := AktBeat;
            PlayClick := true;
          end;
        end;
      end;
    end;
  end else
    LineChanged := false;

  // midi music
  if PlaySentenceMidi then begin

    // stop the music
    if end_ then begin
      MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
      PlaySentenceMidi := false;
      Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
      AktNuta := noteStart;
      Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
      Lyric.Selected := AktNuta;
    end;

    // click
    Text[TextDebug].Text := IntToStr(AktBeat);

    if PlayClick then
    begin
      for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
        if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
        begin
          if Pet > 0 then
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
          MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
          MidiLastNote := Pet;
        end;
    end;
  end; // if PlaySentenceMidi

  // mp3 music
  if PlaySentence then
  begin
    // stop the music
    if end_ then begin
      Music.Stop;
      PlaySentence := false;
      Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
      AktNuta := noteStart;
      Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
      Lyric.Selected := AktNuta;
    end;

    if (Click) and (PlaySentence) then
    begin
      Text[TextDebug].Text := IntToStr(AktBeat);
      if PlayClick then
        Music.PlayClick;
    end; // click
  end;

  // move "cursor"
  if (PlaySentence or PlaySentenceMidi) then
  begin
    for line := 0 to Length(Czesci[0].Czesc) - 1 do
    begin
      for note := 0 to Length(Czesci[0].Czesc[line].Nuta) - 1 do
      begin
        //note change
        if (Czesci[0].Czesc[line].Nuta[note].Start = AktBeat) and
          ((note <> AktNuta) or LineChanged) then
        begin
          Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
          if not LineChanged then
            Inc(AktNuta)
          else
            LineChanged := false;

          Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
          Lyric.AddCzesc(Czesci[0].Akt);
            Lyric.Selected := AktNuta;
        end;
      end;
    end;
  end;

  // midi music
  if PlayOneNoteMidi then
  begin
    MidiPos := USTime.GetTime - MidiTime + MidiStart;
    // stop the music
    if (MidiPos > MidiStop) then
    begin
      MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
      PlayOneNoteMidi := false;
    end;

    // click
    AktBeat := Floor(GetMidBeat(MidiPos - AktSong.GAP / 1000));
    Text[TextDebug].Text := IntToStr(AktBeat);

    if AktBeat <> LastClick then
    begin
      for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
      begin
        if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
        begin
          LastClick := AktBeat;
          if Pet > 0 then
            MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
          MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
          MidiLastNote := Pet;
        end;
      end;
    end;
  end; // if PlayOneNoteMidi

  // mp3 music
  if PlayOneNote then
  begin
    // stop the music
    if (Music.Position > PlayStopTime) then
    begin
      Music.Stop;
      PlayOneNote := false;
    end;

    // click
    if (Click) and (PlaySentence) then
    begin
      AktBeat := Floor(GetMidBeat(Music.Position - AktSong.GAP / 1000));
      Text[TextDebug].Text := IntToStr(AktBeat);
      if AktBeat <> LastClick then
      begin
        for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
        begin
          if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
          begin
            Music.PlayClick;
            LastClick := AktBeat;
          end;
        end;
      end;
    end; // click
  end; // if PlayOneNote

  Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
  Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut);

  // Song info
  if not BPMEditMode then
    Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);

  Text[TextGAP].Text := FloatToStr(AktSong.GAP);

  //Error reading Variables when no Song is loaded
  if not Error then
  begin
    // Note info
    Text[TextNStart].Text :=    IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
    Text[TextNDlugosc].Text :=  IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
    Text[TextNTon].Text :=      IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' ( ' + GetNoteName(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' )';
    Text[TextNText].Text :=              Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;

    //F and G and Medley Mod:
    if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].FreeStyle then
      Text[TextNTon].Text := Text[TextNTon].Text + ' *F*'
    else if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc = 2 then
      Text[TextNTon].Text := Text[TextNTon].Text + ' *G*';

    if MedleyNotes.isStart and (Czesci[0].Akt = MedleyNotes.start.line)
      and (AktNuta = MedleyNotes.start.note) then
      Text[TextNTon].Text := Text[TextNTon].Text + ' MedleyStart';
    if MedleyNotes.isEnd and (Czesci[0].Akt = MedleyNotes.end_.line) and
      (AktNuta = MedleyNotes.end_.note) then
      Text[TextNTon].Text := Text[TextNTon].Text + ' MedleyEnd';

    //preview mod
    if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsStartPreview then
      Text[TextNTon].Text := Text[TextNTon].Text + ' [PreviewStart]';
  end;

  // Text Edit Mode
  if TextEditMode then
    Text[TextNText].Text := Text[TextNText].Text + '|';

  // draw static menu
  inherited Draw;

  // draw notes
  SingDrawNoteLines(20, 305, 780, 15);
  //Error Drawing when no Song is loaded
  if not Error then
  begin
    SingDrawBeatDelimeters(40, 305, 760, 0);
    EditDrawCzesc(40, 410, 760, 0, 15);
  end;

  // draw text
  Lyric.Draw;

end;

procedure TScreenEditSub.onHide;
begin
  MidiOut.Close;
  MidiOut.Free;
  //Music.SetVolume(100);
end;

function TScreenEditSub.GetNoteName(Note: Integer): String;
var N1, N2: Integer;
begin
  if (Note > 0) then
  begin
    N1 := Note mod 12;
    N2 := Note div 12;
  end
  else
  begin
    N1 := (Note + (-Trunc(Note/12)+1)*12) mod 12;
    N2 := -1;
  end;



  case N1 of
    0: Result := 'c';
    1: Result := 'c#';
    2: Result := 'd';
    3: Result := 'd#';
    4: Result := 'e';
    5: Result := 'f';
    6: Result := 'f#';
    7: Result := 'g';
    8: Result := 'g#';
    9: Result := 'a';
    10: Result := 'b';
    11: Result := 'h';
  end;

  case N2 of
    0: Result := UpperCase(Result); //Normal Uppercase Note, 1: Normal lowercase Note
    2: Result := Result + '''';     //One Striped
    3: Result := Result + '''''';   //Two Striped
    4: Result := Result + ''''''''; //etc.
    5: Result := Result + '''''''''';
    6: Result := Result + '''''''''''';
    7: Result := Result + '''''''''''''';
  end;
end;

function TScreenEditSub.GetMedleyLength: real;
begin
  if MedleyNotes.isStart and MedleyNotes.isEnd then
  begin
    Result := GetTimeFromBeat(
      Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Start +
      Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Dlugosc) -
      GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].Start);
  end else
    Result := 0;
end;

end.