aboutsummaryrefslogblamecommitdiffstats
path: root/us_maker_edition/src/screens/UScreenEditSub.pas
blob: 437deec8567d37a001eea1e1752f6ca435800a1b (plain) (tree)







































                                                                        
                    







                
              



                      
           
          

          

    











                              

                               
 


                                             
 

                                
                                 


                                
                                 
                                
                                 

                                
                                 


                                
                                














                                    
                                
                                

                                
 



                                                                              






















































                                                 







                                                                                    


                            

                                      

                                       
                                                                     


                                           


                            
















                                                      

                                                                           

                                                 


                                    








                                                                                                             
                                                                                                    








                                       
                



                

                




































                                                                                                            
                                                         


























                                                                                                   



                                                                       






















                                                                                                              
                                                                                               






                                              
                       








                                              
                       







                                                       

                       
                             


                                            


                                            



                                  








                                           










                                                                                                       

                                  
              










                                                                                               
                       

                                                    
                            



                                            
                     









                                  

                               

                                                                         





                                                                                    
                                                                                         





                                                 

                                                                         
                                     

                               







                                                                                        

                                                                         
                                     

                               









                                                                                                              
                                                                                       




                               
 


                    
                     



                                                                                         
                            

               
 


                       
                     



                                                                                            




                                            

               







                                           
        
 

                         

                                                                    
             



                                                                                             




                                                       
                     


                                                                        
                            




                         
                     










                                                                                               
                     











                                                                                    
                       



                                                        
                              



                                                                     
                       
                                                        
                              





                                                         
                       




                                                        
                              



                                                                     
                       
                                                        
                              





                         
                     







                                                      
                     








                                                      
                     



                                            
                            




                                       
                     



                                            
                              



                 
                     




                                      
                              






                                                    
                              





                                           

                                            
                              






                                 




                                                                                   




                               




                                                                                  

                               























                                                                                                               



                  




























                                                                                      





                                           
                                   
                       
                       
                              





                                                    
                     





                          
                     

                                  






                                                                                                     



















                                                                                
                              











                                                                          
                              







                                                                          
                              





                                                                       
                              






                 
                     

                                  







                                                                                                     
















                                                                          
                              














                                                                          
                              










                                                                                
                              





                                                                      
                              










                                  
                                                                                              
                                                                                                                   













                                                                         
                              




                                           
                       
                              
                              









                                      

                                  
                                
                                                                                                            












                                                                                                     
                              




                                           
                       
                             
                              






















                                                                                                                    




                                                                              
 
                          



                                                                                  
            






                         










                                                                                                        


                                          



                                  



                                
                     













                                                                                                                                                                                                       
                                            
              
                                        
                                 
                                



                                  


                     











                                                                                                                                                                                                       
            
 




                                  



                                                                             






                                  



                                                 

              









                                                                                                   
                                                  

                       
                                      






























                                                                                                                                   
               

                                                                                                                          
      


                                                                                                                                                                                      
               





                                                                                                                                        
               





                                                                                                                                                                                           
               





                                                                                                                                 
                 







                                                                                                                                                                                    
                 





                                                                                                                          











                                                                                                                                                      





                                                          













                                                                            
                  



                                                       
                                
       


                                                           
         



                                                                                    



                                     
                  

                                                       
                                
       


                                                         
         



                                                                             



                                          
                
                               
                   







                                                                                    
                                
       



                                                                                                 













































































































































































































                                                                                                                                           








                                                                                                    

                                   



                                  









                                    
                                         
       






                                                             
 



                                                                    
         





                                                             
        






















                                                                 
      



                                  






















































































































































                                                                                                               










































































                                                                                                


                                                    


































                                                                                                  

                                                











                                                                                                   


















































































































                                                          
                              




                              

                              






                                    


                                              































                                                                                
                                    







                                





                                           
                                     




                          
                                                                                      
















                                                                        

































                                                                              


                                  

                       
                       









                              



                           










                                                            



















































                                                                                                    


                                                                                                    





                                                         

              



                                                                                                      
 



                                                            










                                                             
                       
             

            

                                


                            
                             



                                                      
                    



                              
 
     



























                                                                              



















                                                                                                 



                                                                                                                         
                              

                                        


                                                                     
        
                                                                                     

                   



                                                                                                                         
                              

                                            


                                                                        






                                              
                                                                                             

                        



                                                                                                                         
                              

                                                      


                                                                                  







                                                        
                                                                                                                 


                                                        









































                                                                                                         
 
                    


                                   
                      



                                                  


                                    







                                                                                                           

























                                                                 
                     
                        




                          



                                      
                

                               












                                                     
                                                                                        
                                                                                                             









                                                                   

                                                                         



                               
                                                                                            
                       
                                                                                                          

                                                                                        





                             
                  
                                                                                   
       
                                       































                                                                                                            
              
                                     





                                                   

                         




                                      
                                                                                                  



                                                                                    

                                                                           
               
                                                                                       





                                                      
 




                                                                                                                    





                                                                 

                                                  
                                                      

                











                                                                                                                                                                                        


                   
                                                         
       



                                                                                                                                             
      

                     
         











                                            
                     

              















                                                                            























































                                                                                     
{* UltraStar Deluxe - Karaoke Game
 *
 * UltraStar Deluxe is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *}

unit UScreenEditSub;

interface

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}
{$I switches.inc}

uses
  UMenu,
  UMusic,
  SDL,
  SysUtils,
  UFiles,
  UGraphicClasses,  
  UTime,
  USongs,
  USong,
  UIni,
  ULog,
  UTexture,
  UMenuText,
  UEditorLyrics,
  UFilesystem,
  Math,
  gl,
  {$IFDEF UseMIDIPort}
  MidiOut,
  MidiCons,
  {$ENDIF}
  UThemes,
  UPath;

type
  TVisibleHeaders = record
        Title: UTF8String;
        Artist: UTF8String;
        CoverId:  Integer;
        BackgroundId: Integer;
        Mp3Id:  Integer;
        GAP:  Real;
        Video:  IPath;
        VideoGAP: real;
        BPM:  array of TBPM;
  end;

  TScreenEditSub = class(TMenu)
    private

      AktBeat:          integer;
      //Variable is True if no Song is loaded
      Error:            boolean;

      TextNote:         integer;
      TextSentence:     integer;
{      TextTitle:        integer;
      TextArtist:       integer;
      TextMp3:          integer;
      TextBPM:          integer;
      TextGAP:          integer;}
      TextDebug:        integer;
{      TextNStart:       integer;
      TextNLength:      integer;
      TextNTon:         integer;
      TextNText:        integer;}
      CurrentNote:      integer;
      PlaySentence:     boolean;
      PlaySentenceMidi: boolean;
      PlayVideo:        boolean;
      PlayStopTime:     real;
      LastClick:        integer;
      Click:            boolean;
      CopySrc:          integer;

      {$IFDEF UseMIDIPort}
      MidiOut:          TMidiOutput;
      {$endif}

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

      TextPosition:     integer;
      TextEditMode:     boolean;
      TitleEditMode:    boolean;
      ArtistEditMode:   boolean;

      BackupEditText:   UTF8String; //backup of current text in text-edit-mode
      CurrentEditText:  UTF8String; // current edit text
      editLenghtText:   integer;
      CurrentSlideId:   integer;
      //title header
      TitleSlideId:     integer;
      TitleData:        integer;
      TitleVal:         array of UTF8String;
      SlideTitleIndex:  integer;
      // artist header
      ArtistSlideId:     integer;
      ArtistData:        integer;
      ArtistVal:         array of UTF8String;
      SlideArtistIndex:  integer;
      // mp3 header
      MP3SlideId:     integer;
      MP3Data:        integer;
      MP3Val:         array of UTF8String;
      SlideMP3Index:  integer;
      // Cover header
      CoverSlideId:     integer;
      CoverData:        integer;
      CoverVal:         array of UTF8String;
      SlideCoverIndex:  integer;
      // Background header
      BackgroundSlideId:     integer;
      BackgroundData:        integer;
      BackgroundVal:         array of UTF8String;
      SlideBackgroundIndex:  integer;
      // BPM header
      BPMSlideId:     integer;
      BPMData:        integer;
      BPMVal:         array of UTF8String;
      SlideBPMIndex:  integer;
      // GAP header
      GAPSlideId:     integer;
      GAPData:        integer;
      GAPVal:         array of UTF8String;
      SlideGAPIndex:  integer;
      // Start header
      StartSlideId:     integer;
      StartData:        integer;
      StartVal:         array of UTF8String;
      SlideStartIndex:  integer;
      // Duration header
      DurationSlideId:     integer;
      DurationData:        integer;
      DurationVal:         array of UTF8String;
      SlideDurationIndex:  integer;
      // Tone header
      ToneSlideId:     integer;
      ToneData:        integer;
      ToneVal:         array of UTF8String;
      SlideToneIndex:  integer;
      // Text header
      LyricSlideId:     integer;
      LyricData:        integer;
      LyricVal:         array of UTF8String;
      SlideLyricIndex:  integer;
      // Volume Slide
      VolumeAudioSlideId: integer;
      VolumeMidiSlideId:  integer;
      VolumeClickSlideId: integer;
      VolumeAudioIndex,VolumeMidiIndex,VolumeClickIndex: integer; //for update slide
      VolumeAudio:    array of UTF8String;
      VolumeMidi:    array of UTF8String;
      VolumeClick:    array of UTF8String;
      //  currentX, CurrentY
      CurrentX:   integer;
      CurrentY:   integer;
      Lyric:            TEditorLyrics;

      //undo declaration
      UndoLines:       array of TLines;
      UndoStateNote:      array of integer; //UNDO: note's position  
      CurrentUndoLines: integer;
      UndoHeader: array of TVisibleHeaders;

      //video view
      fCurrentVideo: IVideo;

      procedure DivideBPM;
      procedure MultiplyBPM;
      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);
      procedure CopyToUndo; //copy current Lines,mouse position and headers
      procedure CopyFromUndo; //undo last Lines,mouse position and headers
      procedure DrawStatics;
      procedure DrawInfoBar(x, y, w, h: integer);
      //video view
      procedure StartVideoPreview();
      procedure StopVideoPreview();
      //Note Name Mod
      function GetNoteName(Note: integer): string;
    public
      Tex_Background:     TTexture;
      FadeOut:            boolean;
      constructor Create; override;
      procedure OnShow; override;
      function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override;
      function ParseInputEditText(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
      function ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean; override;
      function Draw: boolean; override;
      procedure OnHide; override;
  end;

implementation

uses
  UGraphic,
  UDraw,
  UMenuInteract,
  UNote,
  USkins,
  ULanguage,
  UTextEncoding,
  UUnicodeUtils;



procedure OnSaveEncodingError(Value: boolean; Data: Pointer);
var
  SResult: TSaveSongResult;
  FilePath: IPath;
  Success: boolean;
begin
  Success := false;
  if (Value) then
  begin
    CurrentSong.Encoding := encUTF8;
    FilePath := CurrentSong.Path.Append(CurrentSong.FileName);
    // create backup file
    FilePath.CopyFile(Path(FilePath.ToUTF8 + '.ansi.bak'), false);
    // store in UTF-8 encoding
    SResult := SaveSong(CurrentSong, Lines[0], FilePath,
             boolean(Data));
    Success := (SResult = ssrOK);
  end;

  if (Success) then
    ScreenPopupInfo.ShowPopup(Language.Translate('INFO_FILE_SAVED'))
  else
    ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED'));
end;

// Method for input parsing. If false is returned, GetNextWindow
// should be checked to know the next window to load;
function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
var
  SDL_ModState:  word;
  R:    real;
  SResult: TSaveSongResult;
begin
  Result := true;

  if TextEditMode or TitleEditMode or ArtistEditMode then
  begin
    Result := ParseInputEditText(PressedKey, CharCode, PressedDown);
  end
  else
  begin

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

  if (PressedDown) then  // Key Down
  begin
    // check normal keys
    case PressedKey of
      SDLK_Q:
        begin
          Result := false;
          Exit;
        end;
      SDLK_S:
        begin
          // Save Song
          SResult := SaveSong(CurrentSong, Lines[0], CurrentSong.Path.Append(CurrentSong.FileName),
                   (SDL_ModState = KMOD_LSHIFT));
          if (SResult = ssrOK) then
          begin
            //ScreenPopupInfo.ShowPopup(Language.Translate('INFO_FILE_SAVED'));
            Text[TextDebug].Text := Language.Translate('INFO_FILE_SAVED');
            SetLength(UndoLines, 0); //clear undo lines
            SetLength(UndoStateNote, 0); //clear undo currentnote state
            SetLength(Undoheader, 0); //clear undo headrers
            CurrentUndoLines := 0;
          end
          else if (SResult = ssrEncodingError) then
          begin
            ScreenPopupCheck.ShowPopup(Language.Translate('ENCODING_ERROR_ASK_FOR_UTF8'), OnSaveEncodingError,
                Pointer(SDL_ModState = KMOD_LSHIFT), true);
          end
          else
          begin
            ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED'));
          end;
          Exit;
        end;

      SDLK_R:   //reload
        begin
          AudioPlayback.Stop;
          {$IFDEF UseMIDIPort}
          MidiOut.Close;
          MidiOut.Free;
          {$ENDIF}
          Lyric.Free;

          onShow;
          Text[TextDebug].Text := 'song reloaded'; //TODO: Language.Translate('SONG_RELOADED');
        end;

      SDLK_D:
        begin
          // Divide lengths by 2
          if (SDL_ModState = KMOD_LSHIFT) then
          begin
            CopyToUndo;
            DivideBPM;
            Exit;
          end;
        end;
      SDLK_M:
        begin
          // Multiply lengths by 2
          if (SDL_ModState = KMOD_LSHIFT) then
          begin
            CopyToUndo;
            MultiplyBPM;
            Exit;
          end;
        end;
      SDLK_C:
        begin
          // Capitalize letter at the beginning of line
          if SDL_ModState = 0 then
            begin
            CopyToUndo;
            LyricsCapitalize;
            Lyric.AddLine(Lines[0].Current);
            Lyric.Selected := CurrentNote;
            end;

          // Correct spaces
          if SDL_ModState = KMOD_LSHIFT then
            begin
              CopyToUndo;
              LyricsCorrectSpaces;
            end;

          // Copy sentence
          if SDL_ModState = KMOD_LCTRL then
            MarkSrc;

          Exit;
        end;
      SDLK_V:
        begin
          if SDL_ModState = 0 then
          begin
              AudioPlayback.Stop;
              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
              CurrentNote := 0;
              AudioPlayback.Position := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
              PlayStopTime := GetTimeFromBeat(Lines[0].Line[Lines[0].High].End_);
              PlaySentence := true;
              AudioPlayback.SetVolume(SelectsS[VolumeAudioSlideId].SelectedOption / 100);
              AudioPlayback.Play;
              LastClick := -100;
              PlayVideo := true;
              StartVideoPreview();
          end;
          // Paste text
          if SDL_ModState = KMOD_LCTRL then
          begin
            if Lines[0].Line[Lines[0].Current].HighNote >= Lines[0].Line[CopySrc].HighNote then
              PasteText
            else
              Log.LogStatus('PasteText: invalid range', 'TScreenEditSub.ParseInput');
          end;

          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then
          begin
            CopyToUndo;
            CopySentence(CopySrc, Lines[0].Current);
          end;
          GoldenRec.KillAll;
        end;
      SDLK_T:
        begin
          // Fixes timings between sentences
          CopyToUndo;
          FixTimings;
          Exit;
        end;
      SDLK_P:
        begin
          if SDL_ModState = 0 then
          begin
            // Play Sentence
            Click := true;
            AudioPlayback.Stop;
            PlayVideo := false;
            StopVideoPreview;
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
            CurrentNote := 0;
            R := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
            if R <= AudioPlayback.Length then
            begin
              AudioPlayback.Position := R;
              PlayStopTime := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
              PlaySentence := true;
              AudioPlayback.SetVolume(SelectsS[VolumeAudioSlideId].SelectedOption / 100);
              AudioPlayback.Play;
              LastClick := -100;
            end;
          end
          else if SDL_ModState = KMOD_LSHIFT then
          begin
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
            CurrentNote := 0;
            PlaySentenceMidi := true;
            PlayVideo := false;
            StopVideoPreview;
            MidiTime := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
            MidiStop := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);

            LastClick := -100;
          end
          else if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then
          begin
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
            CurrentNote := 0;
            PlaySentenceMidi := true;
            PlayVideo := false;
            StopVideoPreview;
            MidiTime  := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start);
            MidiStop  := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_);
            LastClick := -100;

            PlaySentence := true;
            Click := true;
            AudioPlayback.Stop;
            AudioPlayback.Position := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[0].Start)+0{-0.10};
            PlayStopTime := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].End_)+0;
            AudioPlayback.SetVolume(SelectsS[VolumeAudioSlideId].SelectedOption / 100);
            AudioPlayback.Play;
            LastClick := -100;
          end;
          Exit;
        end;

      // Golden Note
      SDLK_G:
        begin
          CopyToUndo;
          if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntGolden) then
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal
          else
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntGolden;
          GoldenRec.KillAll;
          Exit;
        end;

      // Freestyle Note
      SDLK_F:
        begin
          CopyToUndo;
          if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntFreestyle) then
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal
          else
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntFreestyle;
          	GoldenRec.KillAll;

            // update lyrics
            Lyric.AddLine(Lines[0].Current);
            Lyric.Selected := CurrentNote;
          Exit;
        end;
      SDLK_Z:
        begin
          if SDL_ModState = KMOD_LCTRL then
          begin
              CopyFromUndo;
              GoldenRec.KillAll;
          end;
        end;
    end;

    // check special keys
    case PressedKey of
      SDLK_ESCAPE :
//      SDLK_BACKSPACE : // disable to leave editor by backspace key
        begin
          if length(UndoLines) > 0 then
          ScreenPopupcheck.CheckFadeTo(@ScreenSong,'Do you want leave editor without save ?')
          else
            FadeTo(@ScreenSong);
        end;

      SDLK_BACKQUOTE:
        begin
          // Increase Note Length (same as Alt + Right)
          CopyToUndo;
          Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
          if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
            Inc(Lines[0].Line[Lines[0].Current].End_);
          GoldenRec.KillAll;
        end;

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

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

      SDLK_4:
        begin
          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then
          begin
            CopyToUndo;
            CopySentence(CopySrc, Lines[0].Current);
            CopySentence(CopySrc+1, Lines[0].Current+1);
            CopySentence(CopySrc+2, Lines[0].Current+2);
            CopySentence(CopySrc+3, Lines[0].Current+3);
            GoldenRec.KillAll;
          end;

          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then
          begin
            CopyToUndo;
            CopySentences(CopySrc, Lines[0].Current, 4);
            GoldenRec.KillAll;
          end;
        end;
      SDLK_5:
        begin
          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then
          begin
            CopyToUndo;
            CopySentence(CopySrc, Lines[0].Current);
            CopySentence(CopySrc+1, Lines[0].Current+1);
            CopySentence(CopySrc+2, Lines[0].Current+2);
            CopySentence(CopySrc+3, Lines[0].Current+3);
            CopySentence(CopySrc+4, Lines[0].Current+4);
            GoldenRec.KillAll;
          end;

          if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then
          begin
            CopyToUndo;
            CopySentences(CopySrc, Lines[0].Current, 5);
            GoldenRec.KillAll;
          end;
        end;

      SDLK_9:
        begin
          // Decrease GAP
          CopyToUndo;
          if SDL_ModState = 0 then
            CurrentSong.GAP := CurrentSong.GAP - 10;
          if SDL_ModState = KMOD_LSHIFT then
            CurrentSong.GAP := CurrentSong.GAP - 1000;
        end;
      SDLK_0:
        begin
          // Increase GAP
          CopyToUndo;
          if SDL_ModState = 0 then
            CurrentSong.GAP := CurrentSong.GAP + 10;
          if SDL_ModState = KMOD_LSHIFT then
            CurrentSong.GAP := CurrentSong.GAP + 1000;
        end;

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

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

      SDLK_SLASH:
        begin
          CopyToUndo;
          if SDL_ModState = 0 then
          begin
            // Insert start of sentece
            if CurrentNote > 0 then
              DivideSentence;
            GoldenRec.KillAll;
          end;

          if SDL_ModState = KMOD_LSHIFT then
          begin
            // Join next sentence with current
            if Lines[0].Current < Lines[0].High then
              JoinSentence;
            GoldenRec.KillAll;
          end;

          if SDL_ModState = KMOD_LCTRL then
          begin
            // divide note
            DivideNote;
            Lyric.AddLine(Lines[0].Current);
            Lyric.Selected := CurrentNote;
            GoldenRec.KillAll;
          end;

        end;

      SDLK_F4:
        begin
          // Enter Text Edit Mode
          BackupEditText := Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text;
          CurrentEditText := BackupEditText;
          CurrentSlideId := LyricSlideId;
          TextPosition := LengthUTF8(BackupEditText);
          editLenghtText := LengthUTF8(BackupEditText);
          TextEditMode := true;
        end;

      SDLK_SPACE:
        begin
          if (SDL_ModState = 0) or (SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL) then
          begin
            // Play Sentence
            PlaySentenceMidi := false; // stop midi
            PlaySentence := true;
            PlayVideo := false;
            StopVideoPreview;
            Click := false;
            AudioPlayback.Stop;
            AudioPlayback.Position := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
            PlayStopTime := (GetTimeFromBeat(
              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start +
              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length));
            AudioPlayback.SetVolume(SelectsS[VolumeAudioSlideId].SelectedOption / 100);
            AudioPlayback.Play;
            LastClick := -100;
          end;

          if (SDL_ModState = KMOD_LSHIFT) or (SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL) then
          begin
            // Play Midi
            PlaySentenceMidi := true;

            MidiTime := USTime.GetTime;
            MidiStart := GetTimeFromBeat(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
            MidiStop := GetTimeFromBeat(
              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start +
              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);

            LastClick := -100;
          end;
        end;

      SDLK_RETURN:
        begin
           if Interaction = TitleSlideId then
           begin
             BackupEditText := CurrentSong.Title;
             CurrentEditText := BackupEditText;
             editLenghtText := LengthUTF8(BackupEditText);
             CurrentSlideId := TitleSlideId;
             TextPosition := LengthUTF8(BackupEditText);
             TitleEditMode := true;
           end;
           if Interaction = ArtistSlideId then
           begin
             BackupEditText := CurrentSong.Artist;
             CurrentEditText := BackupEditText;
             editLenghtText := LengthUTF8(BackupEditText);
             CurrentSlideId := ArtistSlideId;
             TextPosition := LengthUTF8(BackupEditText);
             ArtistEditMode := true;
           end;

           if Interaction = LyricSlideId then
           begin
             BackupEditText := Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text;
             CurrentEditText := BackupEditText;
             editLenghtText := LengthUTF8(BackupEditText);
             CurrentSlideId := LyricSlideId;
             TextPosition := LengthUTF8(BackupEditText);
             TextEditMode := true;
           end;

        end;

      SDLK_DELETE:
        begin
          if SDL_ModState = KMOD_LCTRL then
          begin
            // deletes current note
            CopyToUndo;
            DeleteNote;
            GoldenRec.KillAll;
          end;
        end;

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

      SDLK_RIGHT:
        begin
          // right
          CopyToUndo;
          if SDL_ModState = 0 then
          begin
            AudioPlayback.Stop;
            PlaySentence := false;
            {$IFDEF UseMIDIPort}
            MidiOut.PutShort($B1, $7, floor(1.27*SelectsS[VolumeMidiSlideId].SelectedOption));
            MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
            PlaySentenceMidi := false;
            {$endif}
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
            Inc(CurrentNote);
            if CurrentNote > Lines[0].Line[Lines[0].Current].HighNote then
              CurrentNote := 0;
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 2;
            Lyric.Selected := CurrentNote;
          end;

          // ctrl + right
          if SDL_ModState = KMOD_LCTRL then
          begin
            if Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length > 1 then
            begin
              Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
              Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
              if CurrentNote = 0 then
              begin
                Inc(Lines[0].Line[Lines[0].Current].Start);
              end;
            end;
            GoldenRec.KillAll;
          end;

          // shift + right
          if SDL_ModState = KMOD_LSHIFT then
          begin
            Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
            if CurrentNote = 0 then
            begin
              Inc(Lines[0].Line[Lines[0].Current].Start);
            end;
            if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
              Inc(Lines[0].Line[Lines[0].Current].End_);
            GoldenRec.KillAll;
          end;

          // alt + right
          if SDL_ModState = KMOD_LALT then
          begin
            Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
            if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
              Inc(Lines[0].Line[Lines[0].Current].End_);
            GoldenRec.KillAll;
          end;

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

        end;

      SDLK_LEFT:
        begin
          // left
          CopyToUndo;
          if SDL_ModState = 0 then
          begin
            AudioPlayback.Stop;
            PlaySentence := false;
            {$IFDEF UseMIDIPort}
            MidiOut.PutShort($B1, $7, floor(1.27*SelectsS[VolumeMidiSlideId].SelectedOption));
            MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
            PlaySentenceMidi := false;
            {$endif}

            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
            Dec(CurrentNote);
            if CurrentNote = -1 then
              CurrentNote := Lines[0].Line[Lines[0].Current].HighNote;
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 2;
            Lyric.Selected := CurrentNote;
          end;

          // ctrl + left
          if SDL_ModState = KMOD_LCTRL then
          begin
            Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
            Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
            if CurrentNote = 0 then
            begin
              Dec(Lines[0].Line[Lines[0].Current].Start);
            end;
            GoldenRec.KillAll;
          end;

          // shift + left
          if SDL_ModState = KMOD_LSHIFT then
          begin
            Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);

            // resizing sentences
            if CurrentNote = 0 then
            begin
              Dec(Lines[0].Line[Lines[0].Current].Start);
            end;

            if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
              Dec(Lines[0].Line[Lines[0].Current].End_);
            GoldenRec.KillAll;
          end;

          // alt + left
          if SDL_ModState = KMOD_LALT then
          begin
            if Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length > 1 then
            begin
              Dec(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
              if CurrentNote = Lines[0].Line[Lines[0].Current].HighNote then
                Dec(Lines[0].Line[Lines[0].Current].End_);
            end;
            GoldenRec.KillAll;
          end;

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

        end;

      SDLK_DOWN:
        begin

          // skip to next sentence
          if SDL_ModState = 0 then
          begin
            {$IFDEF UseMIDIPort}
            MidiOut.PutShort($B1, $7, floor(1.27*SelectsS[VolumeMidiSlideId].SelectedOption));
            MidiOut.PutShort(MIDI_NOTEOFF or 1, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
            PlaySentenceMidi := false;
            {$ENDIF}

            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
            Inc(Lines[0].Current);
            CurrentNote := 0;
            if Lines[0].Current > Lines[0].High then
              Lines[0].Current := 0;
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 2;

            Lyric.AddLine(Lines[0].Current);
            Lyric.Selected := 0;
            AudioPlayback.Stop;
            PlaySentence := false;
            GoldenRec.KillAll;
          end;

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

        end;

      SDLK_UP:
        begin

          // skip to previous sentence
          if SDL_ModState = 0 then
          begin
            AudioPlayback.Stop;
            PlaySentence := false;
            {$IFDEF UseMIDIPort}
            MidiOut.PutShort(MIDI_NOTEOFF or 1, $7, floor(1.27*SelectsS[VolumeMidiSlideId].SelectedOption));
            MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
            PlaySentenceMidi := false;
            {$endif}

            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
            Dec(Lines[0].Current);
            CurrentNote := 0;
            if Lines[0].Current = -1 then
              Lines[0].Current := Lines[0].High;
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 2;

            Lyric.AddLine(Lines[0].Current);
            Lyric.Selected := 0;
            GoldenRec.KillAll;
          end;

          // increase tone
          if SDL_ModState = KMOD_LCTRL then
          begin
            CopyToUndo;
            TransposeNote(1);
            GoldenRec.KillAll;
          end;
        end;

      end; // case
    end;
  end; // if
end;

function TScreenEditSub.ParseInputEditText(PressedKey: cardinal; CharCode: UCS4Char; 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 (PressedDown) then
  begin
    // check normal keys
    if (IsPrintableChar(CharCode)) then
    begin
      CurrentEditText :=
      UTF8Copy(CurrentEditText, 1,TextPosition) + UCS4ToUTF8String(CharCode) +
      UTF8Copy(CurrentEditText, TextPosition+1, LengthUTF8(CurrentEditText));
      inc(editLenghtText);
      inc(TextPosition);

      if TextEditMode then
        begin
        Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text := CurrentEditText;
        Lyric.AddLine(Lines[0].Current);
        Lyric.Selected := CurrentNote;
        end;
      Exit;
    end;

    // check special keys
    case PressedKey of
      SDLK_ESCAPE:
        begin
          if TextEditMode then Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text := BackupEditText;
          if TitleEditMode then
          begin
            CurrentSong.Title := BackupEditText;
            SelectsS[CurrentSlideId].TextOpt[0].Text := BackupEditText;
          end;
          if ArtistEditMode then
          begin
            CurrentSong.Artist := BackupEditText;
            SelectsS[CurrentSlideId].TextOpt[0].Text := BackupEditText;
          end;
          Lyric.AddLine(Lines[0].Current);
          Lyric.Selected := CurrentNote;
          TextEditMode := false;
          TitleEditMode := false;
          ArtistEditMode := false;
          editLenghtText := 0;
          TextPosition := -1;
        end;
      SDLK_F4, SDLK_RETURN:
        begin
          // Exit Text Edit Mode
          CopyToUndo;
          if TitleEditMode then
          begin
            CurrentSong.Title := UTF8Copy(CurrentEditText, 1, TextPosition) + UTF8Copy(CurrentEditText, TextPosition+1, LengthUTF8(CurrentEditText)-TextPosition);
            SelectsS[CurrentSlideId].TextOpt[0].Text := CurrentEditText;
          end;
          if ArtistEditMode then
          begin
            CurrentSong.Artist := UTF8Copy(CurrentEditText, 1, TextPosition) + UTF8Copy(CurrentEditText, TextPosition+1, LengthUTF8(CurrentEditText)-TextPosition);
            SelectsS[CurrentSlideId].TextOpt[0].Text := CurrentEditText;
          end;
          if TextEditMode then
          begin
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text := UTF8Copy(CurrentEditText, 1, TextPosition) + UTF8Copy(CurrentEditText, TextPosition+1, LengthUTF8(CurrentEditText)-TextPosition);
            SelectsS[CurrentSlideId].TextOpt[0].Text := CurrentEditText;
            Lyric.AddLine(Lines[0].Current);
          end;
          Lyric.Selected := CurrentNote;
          TitleEditMode := false;
          TextEditMode := false;
          ArtistEditMode := false;
          editLenghtText := 0;
          TextPosition := -1;
          CurrentSlideId := -1;
        end;
      SDLK_BACKSPACE:
        begin
          UTF8Delete(CurrentEditText, TextPosition, 1);
          dec(TextPosition);
          if TextEditMode then
          begin
            Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text := UTF8Copy(CurrentEditText, 1, TextPosition) + UTF8Copy(CurrentEditText, TextPosition+1, LengthUTF8(CurrentEditText)-TextPosition);
            Lyric.AddLine(Lines[0].Current);
            Lyric.Selected := CurrentNote;
          end;
        end;
      SDLK_DELETE:
        begin
            UTF8Delete(CurrentEditText, TextPosition+1, 1);
        end;

      SDLK_RIGHT:
        begin
          // right
          if SDL_ModState = 0 then
          begin
            if (TextPosition >= 0) and (TextPosition < editLenghtText-1) then
                TextPosition := TextPosition + 1
            else
              TextPosition := 0;
          end;
        end;
      SDLK_LEFT:
        begin
          // left
          if SDL_ModState = 0 then
          begin
            if TextPosition > 0 then
                TextPosition := TextPosition - 1
            else
                TextPosition := editLenghtText-1;
          end;
      end;
    end; //case
  end; //if (PressedDown)
end;

function TScreenEditSub.ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean;
var
  nBut: integer;
  Action: TMouseClickAction;
begin
  // transfer mousecords to the 800x600 raster we use to draw
  X := Round((X / (ScreenW / Screens)) * RenderW);
  if (X > RenderW) then
    X := X - RenderW;
  Y := Round((Y / ScreenH) * RenderH);

  CurrentX := X;
  CurrentY := X;

  Result := true;
  nBut := InteractAt(X, Y);
  Action := maNone;

  if nBut >= 0 then
  begin
    //select on mouse-over
    if nBut <> Interaction then
      SetInteraction(nBut);
  end;

  if (BtnDown) then
  begin
      if (MouseButton = SDL_BUTTON_LEFT) then
      begin
        //click button or SelectS
        if (Interactions[nBut].Typ = iSelectS) then
          begin
          Action := SelectsS[Interactions[nBut].Num].OnClick(X, Y);
          end
          else
            Action := maReturn;
      end;
  end;
  // changed cover
  if ((CoverSlideId = Interactions[nBut].Num) and (Action = maLeft) and (SelectsS[Interactions[nBut].Num].SelectedOption > 0)) then
  begin
    CopyToUndo;
    SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption -1;
    CurrentSong.Cover := Path(SelectsS[Interactions[nBut].Num].TextOptT[SelectsS[Interactions[nBut].Num].SelectedOption]);
  end;

  if ((CoverSlideId = Interactions[nBut].Num) and (Action = maRight) and (SelectsS[Interactions[nBut].Num].SelectedOption < Length(SelectsS[Interactions[nBut].Num].TextOptT)-1)) then
  begin
    CopyToUndo;
    SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption +1;
    CurrentSong.Cover := Path(SelectsS[Interactions[nBut].Num].TextOptT[SelectsS[Interactions[nBut].Num].SelectedOption]);
  end;

  if ((BackgroundSlideId = Interactions[nBut].Num) and (Action = maLeft) and (SelectsS[Interactions[nBut].Num].SelectedOption > 0)) then
  begin
    CopyToUndo;
    SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption -1;
    CurrentSong.Background := Path(SelectsS[Interactions[nBut].Num].TextOptT[SelectsS[Interactions[nBut].Num].SelectedOption]);
  end;

  if ((BackgroundSlideId = Interactions[nBut].Num) and (Action = maRight) and (SelectsS[Interactions[nBut].Num].SelectedOption < Length(SelectsS[Interactions[nBut].Num].TextOptT)-1)) then
  begin
    CopyToUndo;
    SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption +1;
    CurrentSong.Background := Path(SelectsS[Interactions[nBut].Num].TextOptT[SelectsS[Interactions[nBut].Num].SelectedOption]);
  end;

  if ((Mp3SlideId = Interactions[nBut].Num) and (Action = maLeft) and (SelectsS[Interactions[nBut].Num].SelectedOption > 0)) then
    begin
      CopyToUndo;
      SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption -1;
      CurrentSong.Mp3 := Path(SelectsS[Interactions[nBut].Num].TextOptT[SelectsS[Interactions[nBut].Num].SelectedOption]);
      AudioPlayback.Close;
      AudioPlayback.Open(CurrentSong.Path.Append(CurrentSong.Mp3));
    end;

  if ((Mp3SlideId = Interactions[nBut].Num) and (Action = maRight) and (SelectsS[Interactions[nBut].Num].SelectedOption < Length(SelectsS[Interactions[nBut].Num].TextOptT)-1)) then
    begin
      CopyToUndo;
      SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption +1;
      CurrentSong.Mp3 := Path(SelectsS[Interactions[nBut].Num].TextOptT[SelectsS[Interactions[nBut].Num].SelectedOption]);
      AudioPlayback.Close;
      AudioPlayback.Open(CurrentSong.Path.Append(CurrentSong.Mp3));
    end;

  if (((VolumeAudioSlideId = Interactions[nBut].Num) or (VolumeMidiSlideId = Interactions[nBut].Num) or (VolumeClickSlideId = Interactions[nBut].Num))
    and (Action = maLeft) and (SelectsS[Interactions[nBut].Num].SelectedOption > 0)) then
  begin
      SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption -1;
  end;

  if (((VolumeAudioSlideId = Interactions[nBut].Num) or (VolumeMidiSlideId = Interactions[nBut].Num) or (VolumeClickSlideId = Interactions[nBut].Num))
    and (Action = maRight) and (SelectsS[Interactions[nBut].Num].SelectedOption < Length(SelectsS[Interactions[nBut].Num].TextOptT)-1)) then
  begin
      SelectsS[Interactions[nBut].Num].SelectedOption := SelectsS[Interactions[nBut].Num].SelectedOption +1;
  end;

  case Action of
    maReturn: Result := ParseInput(SDLK_RETURN, 0, true);
//    maLeft:   Result := ParseInput(SDLK_LEFT, 0, true);
//    maRight:  Result := ParseInput(SDLK_RIGHT, 0, true);
    end;

end;

{
procedure TScreenEditSub.NewBeat;
begin
  // click
  for Pet := 0 to Lines[0].Line[Lines[0].Current].HighNut do
    if (Lines[0].Line[Lines[0].Current].Note[Pet].Start = Czas.AktBeat) then
      Music.PlayClick;
end;
}

procedure TScreenEditSub.DivideBPM;
var
  i,j:    integer;

begin
  CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM / 2;

  for i := 0 to Lines[0].High do
  begin
    Lines[0].Line[i].Start := Lines[0].Line[i].Start div 2;
    Lines[0].Line[i].End_  := Lines[0].Line[i].End_ div 2;
    for j := 0 to Lines[0].Line[i].HighNote do
    begin
      Lines[0].Line[i].Note[j].Start  := Lines[0].Line[i].Note[j].Start div 2;
      Lines[0].Line[i].Note[j].Length := Round(Lines[0].Line[i].Note[j].Length / 2);
    end; // j
  end; // i
end;

procedure TScreenEditSub.MultiplyBPM;
var
  i,j:    integer;
begin
  CurrentSong.BPM[0].BPM := CurrentSong.BPM[0].BPM * 2;
  for i := 0 to Lines[0].High do
  begin
    Lines[0].Line[i].Start := Lines[0].Line[i].Start * 2;
    Lines[0].Line[i].End_  := Lines[0].Line[i].End_ * 2;
    for j := 0 to Lines[0].Line[i].HighNote do
    begin
      Lines[0].Line[i].Note[j].Start  := Lines[0].Line[i].Note[j].Start * 2;
      Lines[0].Line[i].Note[j].Length := Lines[0].Line[i].Note[j].Length * 2;
    end; // i
  end; // j
end;

procedure TScreenEditSub.LyricsCapitalize;
var
  i:    integer;
  //N:    integer; // temporary
  S:    UTF8String;
begin
  // temporary
  {
  for C := 0 to Lines[0].High do
    for N := 0 to Lines[0].Line[C].HighNut do
      Lines[0].Line[C].Note[N].Text := UTF8LowerCase(Lines[0].Line[C].Note[N].Text);
  }

  for i := 0 to Lines[0].High do
  begin
    S := UTF8UpperCase(UTF8Copy(Lines[0].Line[i].Note[0].Text, 1, 1));
    S := S + UTF8Copy(Lines[0].Line[i].Note[0].Text, 2, Length(Lines[0].Line[i].Note[0].Text)-1);
    Lines[0].Line[i].Note[0].Text := S;
  end; // i
end;

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

    // move spaces on the start to the end of the previous note
    for N := 1 to Lines[0].Line[C].HighNote do
    begin
      while (Copy(Lines[0].Line[C].Note[N].Text, 1, 1) = ' ') do
      begin
        Lines[0].Line[C].Note[N].Text := Copy(Lines[0].Line[C].Note[N].Text, 2, 100);
        Lines[0].Line[C].Note[N-1].Text := Lines[0].Line[C].Note[N-1].Text + ' ';
      end;
    end; // N

    // correct '-'  to '- '
    for N := 0 to Lines[0].Line[C].HighNote do
    begin
      if Lines[0].Line[C].Note[N].Text = '-' then
        Lines[0].Line[C].Note[N].Text := '- ';
    end; // N

    // add space to the previous note when the current word is '- '
    for N := 1 to Lines[0].Line[C].HighNote do
    begin
      if Lines[0].Line[C].Note[N].Text  = '- ' then
        Lines[0].Line[C].Note[N-1].Text := Lines[0].Line[C].Note[N-1].Text + ' ';
    end; // N

    // correct too many spaces at the end of note
    for N := 0 to Lines[0].Line[C].HighNote do
    begin
      while Copy(Lines[0].Line[C].Note[N].Text, Length(Lines[0].Line[C].Note[N].Text)-1, 2) = '  ' do
        Lines[0].Line[C].Note[N].Text := Copy(Lines[0].Line[C].Note[N].Text, 1, Length(Lines[0].Line[C].Note[N].Text)-1);
    end; // N

    // and correct if there is no space at the end of sentence
    N := Lines[0].Line[C].HighNote;
    if Copy(Lines[0].Line[C].Note[N].Text, Length(Lines[0].Line[C].Note[N].Text), 1) <> ' ' then
      Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N].Text + ' ';

  end; // C
end;

procedure TScreenEditSub.FixTimings;
var
  C:    integer;
  S:    integer;
  Min:  integer;
  Max:  integer;
begin
  for C := 1 to Lines[0].High do
  begin
    with Lines[0].Line[C-1] do
    begin
      Min := Note[HighNote].Start + Note[HighNote].Length;
      Max := Lines[0].Line[C].Note[0].Start;
      case (Max - Min) of
        0:    S := Max;
        1:    S := Max;
        2:    S := Max - 1;
        3:    S := Max - 2;
        else
          if ((Max - Min) > 4) then
            S := Min + 2
          else
            S := Max;
      end; // case

      Lines[0].Line[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;
begin
  // increase sentence length by 1
  CLen := Length(Lines[0].Line);
  SetLength(Lines[0].Line, CLen + 1);
  Inc(Lines[0].Number);
  Inc(Lines[0].High);

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

  // clear and set new sentence
  CNew := CStart + 1;
  NStart := CurrentNote;
  Lines[0].Line[CNew].Start := Lines[0].Line[CStart].Note[NStart].Start;
  Lines[0].Line[CNew].Lyric := '';
  Lines[0].Line[CNew].End_ := 0;
  Lines[0].Line[CNew].BaseNote := 0;//High(integer); // TODO: High (integer) will causes a memory exception later in this procedure. Weird!
  Lines[0].Line[CNew].HighNote := -1;
  SetLength(Lines[0].Line[CNew].Note, 0);

  // move right notes to new sentences
  NHigh := Lines[0].Line[CStart].HighNote;
  for N := NStart to NHigh do
  begin
    // increase sentence counters
    with Lines[0].Line[CNew] do
    begin
      Inc(HighNote);
      SetLength(Note, HighNote + 1);
      Note[HighNote] := Lines[0].Line[CStart].Note[N];
      End_ := Note[HighNote].Start + Note[HighNote].Length;
      
      if Note[HighNote].Tone < BaseNote then
        BaseNote := Note[HighNote].Tone;
    end;
  end;

  // clear old notes and set sentence counters
  Lines[0].Line[CStart].HighNote := NStart - 1;
  Lines[0].Line[CStart].End_ := Lines[0].Line[CStart].Note[NStart-1].Start +
    Lines[0].Line[CStart].Note[NStart-1].Length;
  SetLength(Lines[0].Line[CStart].Note, Lines[0].Line[CStart].HighNote + 1);

  //recalculate BaseNote of the divided Sentence
  with Lines[0].Line[CStart] do
  begin
    BaseNote := High(integer);

    for N := 0 to HighNote do
      if Note[N].Tone < BaseNote then
        BaseNote := Note[N].Tone;
  end;

  Lines[0].Current := Lines[0].Current + 1;
  CurrentNote := 0;
  Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 2;
  Lyric.AddLine(Lines[0].Current);
end;

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

  // set new sentence
  NStart := Lines[0].Line[C].HighNote + 1;
  Lines[0].Line[C].HighNote := Lines[0].Line[C].HighNote + Lines[0].Line[C+1].HighNote + 1;
  SetLength(Lines[0].Line[C].Note, Lines[0].Line[C].HighNote + 1);

  // move right notes to new sentences
  for N := 0 to Lines[0].Line[C+1].HighNote do
  begin
    NDst := NStart + N;
    Lines[0].Line[C].Note[NDst] := Lines[0].Line[C+1].Note[N];
  end;

  // increase sentence counters
  NDst := Lines[0].Line[C].HighNote;
  Lines[0].Line[C].End_ := Lines[0].Line[C].Note[NDst].Start +
    Lines[0].Line[C].Note[NDst].Length;

  // move needed sentences to one backward.
  for C := Lines[0].Current + 1 to Lines[0].High - 1 do
    Lines[0].Line[C] := Lines[0].Line[C+1];

  // increase sentence length by 1
  SetLength(Lines[0].Line, Length(Lines[0].Line) - 1);
  Dec(Lines[0].Number);
  Dec(Lines[0].High);
end;

procedure TScreenEditSub.DivideNote;
var
  C:    integer;
  N:    integer;
begin
  C := Lines[0].Current;

  with Lines[0].Line[C] do
  begin
    Inc(HighNote);
    SetLength(Note, HighNote + 1);

    // we copy all notes including selected one
    for N := HighNote downto CurrentNote+1 do
    begin
      Note[N] := Note[N-1];
    end;

    // Note[Cur] and Note[Cur + 1] is identical at this point
    // modify first note
    Note[CurrentNote].Length := Note[CurrentNote+1].Length div 2 + Note[CurrentNote+1].Length mod 2;

    // 2nd note
    Note[CurrentNote+1].Start := Note[CurrentNote].Start + Note[CurrentNote].Length;
    Note[CurrentNote+1].Length := Note[CurrentNote + 1].Length div 2;

    Note[CurrentNote+1].Text := '~';
    Note[CurrentNote+1].Color := 1;
  end;

  // update lyric display
  Lyric.AddLine(Lines[0].Current);
  Lyric.Selected := CurrentNote;
end;

procedure TScreenEditSub.DeleteNote;
var
  C:    integer;
  N:    integer;
begin
  C := Lines[0].Current;

  //Do Not delete Last Note
  if (Lines[0].Line[C].HighNote > 0) then
  begin
    // we copy all notes from the next to the selected one
    for N := CurrentNote+1 to Lines[0].Line[C].HighNote do
    begin
      Lines[0].Line[C].Note[N-1] := Lines[0].Line[C].Note[N];
    end;
    
    Dec(Lines[0].Line[C].HighNote);

    SetLength(Lines[0].Line[C].Note, Lines[0].Line[C].HighNote + 1);

    // last note was deleted
    if (CurrentNote > Lines[0].Line[C].HighNote) then
    begin
      // select new last note
      CurrentNote := Lines[0].Line[C].HighNote;

      // correct Line ending
      with Lines[0].Line[C] do
        End_ := Note[HighNote].Start + Note[HighNote].Length;
    end;

    Lines[0].Line[C].Note[CurrentNote].Color := 2;
  end
  // Last Note of current Sentence Deleted - > Delete Sentence
  // if there are more than two left
  else if (Lines[0].High > 1) then
  begin
    //Move all Sentences after the current to the Left
    for N := C+1 to Lines[0].High do
      Lines[0].Line[N-1] := Lines[0].Line[N];

    //Delete Last Sentence
    SetLength(Lines[0].Line, Lines[0].High);
    Lines[0].High := High(Lines[0].Line);
    Lines[0].Number := Length(Lines[0].Line);

    CurrentNote := 0;
    if (C > 0) then
      Lines[0].Current := C - 1
    else
      Lines[0].Current := 0;

    Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 2;
  end;

  // update lyric display
  Lyric.AddLine(Lines[0].Current);
  Lyric.Selected := CurrentNote;
end;

procedure TScreenEditSub.TransposeNote(Transpose: integer);
begin
  Inc(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone, Transpose);
end;

procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
var
  C:  integer;
  N:  integer;
begin
  for C := 0 to Lines[0].High do
  begin
    Lines[0].Line[C].BaseNote := Lines[0].Line[C].BaseNote + Tone;
    for N := 0 to Lines[0].Line[C].HighNote do
      Lines[0].Line[C].Note[N].Tone := Lines[0].Line[C].Note[N].Tone + Tone;
  end;
end;

procedure TScreenEditSub.MoveAllToEnd(Move: integer);
var
  C:    integer;
  N:    integer;
  NStart: integer;
begin
  for C := Lines[0].Current to Lines[0].High do
  begin
    NStart := 0;
    if C = Lines[0].Current then
      NStart := CurrentNote;
    for N := NStart to Lines[0].Line[C].HighNote do
    begin
      Inc(Lines[0].Line[C].Note[N].Start, Move); // move note start

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

      if N = Lines[0].Line[C].HighNote then // fix ending
        Inc(Lines[0].Line[C].End_, Move);

    end; // for
  end; // for
end;

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

  for N := Lines[0].Line[C].HighNut downto 1 do
  begin
    Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N-1].Text;
  end; // for

  Lines[0].Line[C].Note[0].Text := '- ';
  }

  C := Lines[0].Current;
  NHigh := Lines[0].Line[C].HighNote;

  // last word
  Lines[0].Line[C].Note[NHigh].Text := Lines[0].Line[C].Note[NHigh-1].Text + Lines[0].Line[C].Note[NHigh].Text;

  // other words
  for N := NHigh - 1 downto CurrentNote + 1 do
  begin
    Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N-1].Text;
  end; // for
  Lines[0].Line[C].Note[CurrentNote].Text := '- ';
end;

procedure TScreenEditSub.MarkSrc;
begin
  CopySrc := Lines[0].Current;
end;

procedure TScreenEditSub.PasteText;
var
  C:    integer;
  N:    integer;
begin
  C := Lines[0].Current;

  for N := 0 to Lines[0].Line[CopySrc].HighNote do
    Lines[0].Line[C].Note[N].Text := Lines[0].Line[CopySrc].Note[N].Text;
end;

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

  SetLength(Lines[0].Line[Dst].Note, Lines[0].Line[Src].HighNote + 1);
  Lines[0].Line[Dst].HighNote := Lines[0].Line[Src].HighNote;
  for N := 0 to Lines[0].Line[Src].HighNote do
  begin
    Lines[0].Line[Dst].Note[N].Text := Lines[0].Line[Src].Note[N].Text;
    Lines[0].Line[Dst].Note[N].Length := Lines[0].Line[Src].Note[N].Length;
    Lines[0].Line[Dst].Note[N].Tone := Lines[0].Line[Src].Note[N].Tone;
    Lines[0].Line[Dst].Note[N].Start := Lines[0].Line[Src].Note[N].Start + TD;
  end;
  N := Lines[0].Line[Src].HighNote;
  Lines[0].Line[Dst].End_ := Lines[0].Line[Dst].Note[N].Start + Lines[0].Line[Dst].Note[N].Length;
end;

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

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

  // prepares new sentences: sets sentence start and create first note
  for C := 1 to Num-1 do
  begin
    Lines[0].Line[Dst + C].Start := Lines[0].Line[Dst + C - 1].Note[0].Start +
      (Lines[0].Line[Src + C].Note[0].Start - Lines[0].Line[Src + C - 1].Note[0].Start);
    SetLength(Lines[0].Line[Dst + C].Note, 1);
    Lines[0].Line[Dst + C].HighNote := 0;
    Lines[0].Line[Dst + C].Note[0].Start := Lines[0].Line[Dst + C].Start;
    Lines[0].Line[Dst + C].Note[0].Length := 1;
    Lines[0].Line[Dst + C].End_ := Lines[0].Line[Dst + C].Start + 1;
  end;

  // increase counters
  Lines[0].Number := Lines[0].Number + Num - 1;
  Lines[0].High := Lines[0].High + Num - 1;

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

procedure TScreenEditSub.CopyToUndo;
var
 I,J: integer;
begin
  SetLength(UndoLines, high(UndoLines)+2);
  CurrentUndoLines := high(UndoLines);
  SetLength(UndoStateNote, CurrentUndoLines+1);
  SetLength(UndoHeader, CurrentUndoLines+1);

  Undoheader[CurrentUndoLines].Title := CurrentSong.Title;
  Undoheader[CurrentUndoLines].Artist := CurrentSong.Artist;
  Undoheader[CurrentUndoLines].CoverId := SelectsS[CoverSlideId].SelectedOption;
  Undoheader[CurrentUndoLines].BackgroundId := SelectsS[BackgroundSlideId].SelectedOption;
  Undoheader[CurrentUndoLines].Mp3Id := SelectsS[Mp3SlideId].SelectedOption;
  Undoheader[CurrentUndoLines].GAP  := CurrentSong.GAP;
  Undoheader[CurrentUndoLines].Video := CurrentSong.Video;
  Undoheader[CurrentUndoLines].VideoGAP := CurrentSong.VideoGAP;
  SetLength(Undoheader[CurrentUndoLines].BPM, length(CurrentSong.BPM));
  for I:=0 to length(CurrentSong.BPM)-1 do
  begin
    Undoheader[CurrentUndoLines].BPM[I].BPM := CurrentSong.BPM[I].BPM;
    Undoheader[CurrentUndoLines].BPM[I].StartBeat := CurrentSong.BPM[I].StartBeat;
  end;

  UndoStateNote[CurrentUndoLines] := currentnote;

  UndoLines[CurrentUndoLines].Current := Lines[0].Current;
  UndoLines[CurrentUndoLines].High := Lines[0].High;
  UndoLines[CurrentUndoLines].Number := Lines[0].Number;
  UndoLines[CurrentUndoLines].Resolution := Lines[0].Resolution;
  UndoLines[CurrentUndoLines].NotesGAP := Lines[0].NotesGAP;
  UndoLines[CurrentUndoLines].ScoreValue := Lines[0].ScoreValue;
  SetLength(UndoLines[CurrentUndoLines].Line, length(Lines[0].Line));

  for I:=0 to length(Lines[0].Line)-1 do
  begin
    UndoLines[CurrentUndoLines].Line[I].Start := Lines[0].Line[I].Start;
    UndoLines[CurrentUndoLines].Line[I].Lyric := Lines[0].Line[I].Lyric;
    UndoLines[CurrentUndoLines].Line[I].End_ := Lines[0].Line[I].End_;
    UndoLines[CurrentUndoLines].Line[I].BaseNote := Lines[0].Line[I].BaseNote;
    UndoLines[CurrentUndoLines].Line[I].HighNote := Lines[0].Line[I].HighNote;
    UndoLines[CurrentUndoLines].Line[I].TotalNotes := Lines[0].Line[I].TotalNotes;
    UndoLines[CurrentUndoLines].Line[I].LastLine := Lines[0].Line[I].LastLine;

    SetLength(UndoLines[CurrentUndoLines].Line[I].Note, length(Lines[0].Line[I].Note));
    for J:=0 to length(Lines[0].Line[I].Note)-1 do
    begin
      UndoLines[CurrentUndoLines].Line[I].Note[J].Color := Lines[0].Line[I].Note[J].Color;
      UndoLines[CurrentUndoLines].Line[I].Note[J].Start := Lines[0].Line[I].Note[J].Start;
      UndoLines[CurrentUndoLines].Line[I].Note[J].Length := Lines[0].Line[I].Note[J].Length;
      UndoLines[CurrentUndoLines].Line[I].Note[J].Tone := Lines[0].Line[I].Note[J].Tone;
      UndoLines[CurrentUndoLines].Line[I].Note[J].Text := Lines[0].Line[I].Note[J].Text;
      UndoLines[CurrentUndoLines].Line[I].Note[J].NoteType := Lines[0].Line[I].Note[J].NoteType;
    end; //for J
  end; //for I
end;

procedure TScreenEditSub.CopyFromUndo;
var
 I,J: integer;

begin

CurrentUndoLines := high(UndoLines);

if CurrentUndoLines >= 0 then
begin
  CurrentSong.Title := Undoheader[CurrentUndoLines].Title;
  CurrentSong.Artist := Undoheader[CurrentUndoLines].Artist;
  SelectsS[CoverSlideId].SelectedOption := Undoheader[CurrentUndoLines].CoverId;
  SelectsS[BackgroundSlideId].SelectedOption := Undoheader[CurrentUndoLines].BackgroundId;
  SelectsS[Mp3SlideId].SelectedOption := Undoheader[CurrentUndoLines].Mp3Id;
  CurrentSong.GAP := Undoheader[CurrentUndoLines].GAP;
  CurrentSong.Video := Undoheader[CurrentUndoLines].Video;
  CurrentSong.VideoGAP := Undoheader[CurrentUndoLines].VideoGAP;

  currentnote := UndoStateNote[high(UndoStateNote)];

  SetLength(CurrentSong.BPM, length(Undoheader[CurrentUndoLines].BPM));
  for I:=0 to length(Undoheader[CurrentUndoLines].BPM)-1 do
  begin
    CurrentSong.BPM[I].BPM := Undoheader[CurrentUndoLines].BPM[I].BPM;
    CurrentSong.BPM[I].StartBeat := Undoheader[CurrentUndoLines].BPM[I].StartBeat;
  end;
  Lines[0].Current := UndoLines[CurrentUndoLines].Current;
  Lines[0].High := UndoLines[CurrentUndoLines].High;
  Lines[0].Number := UndoLines[CurrentUndoLines].Number;
  Lines[0].Resolution := UndoLines[CurrentUndoLines].Resolution;
  Lines[0].NotesGAP := UndoLines[CurrentUndoLines].NotesGAP;
  Lines[0].ScoreValue := UndoLines[CurrentUndoLines].ScoreValue;
  SetLength(Lines[0].Line, length(UndoLines[CurrentUndoLines].Line));
  for I:=0 to length(UndoLines[CurrentUndoLines].Line)-1 do
  begin
      Lines[0].Line[I].Start := UndoLines[CurrentUndoLines].Line[I].Start;
      Lines[0].Line[I].Lyric := UndoLines[CurrentUndoLines].Line[I].Lyric;
      Lines[0].Line[I].End_ := UndoLines[CurrentUndoLines].Line[I].End_;
      Lines[0].Line[I].BaseNote := UndoLines[CurrentUndoLines].Line[I].BaseNote;
      Lines[0].Line[I].HighNote := UndoLines[CurrentUndoLines].Line[I].HighNote;
      Lines[0].Line[I].TotalNotes := UndoLines[CurrentUndoLines].Line[I].TotalNotes;
      Lines[0].Line[I].LastLine := UndoLines[CurrentUndoLines].Line[I].LastLine;

      SetLength(Lines[0].Line[I].Note, length(UndoLines[CurrentUndoLines].Line[I].Note));
      for J:=0 to length(UndoLines[CurrentUndoLines].Line[I].Note)-1 do
      begin
        Lines[0].Line[I].Note[J].Color := UndoLines[CurrentUndoLines].Line[I].Note[J].Color;
        Lines[0].Line[I].Note[J].Start := UndoLines[CurrentUndoLines].Line[I].Note[J].Start;
        Lines[0].Line[I].Note[J].Length := UndoLines[CurrentUndoLines].Line[I].Note[J].Length;
        Lines[0].Line[I].Note[J].Tone := UndoLines[CurrentUndoLines].Line[I].Note[J].Tone;
        Lines[0].Line[I].Note[J].Text := UndoLines[CurrentUndoLines].Line[I].Note[J].Text;
        log.LogError(Lines[0].Line[I].Note[J].Text);
        Lines[0].Line[I].Note[J].NoteType := UndoLines[CurrentUndoLines].Line[I].Note[J].NoteType;
      end; //for J
  end; //for I
  SetLength(UndoStateNote, high(UndoStateNote));
  SetLength(UndoHeader, high(UndoLines));
  SetLength(UndoLines, high(UndoLines));
  Text[TextDebug].Text := Language.Translate('INFO_UNDO');
  // to refresh all headers
  SelectsS[LyricSlideId].TextOpt[0].Text := Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text;
  SelectsS[ArtistSlideId].TextOpt[0].Text := CurrentSong.Artist;
  SelectsS[TitleSlideId].TextOpt[0].Text := CurrentSong.Title;
  Lyric.AddLine(Lines[0].Current);
  Lyric.Selected := CurrentNote;
end; //if CurrentUndoLines
end;


procedure TScreenEditSub.DrawStatics;
var
  x, y, w, h: Integer;
begin
  //Theme:
  //bg
  glDisable(GL_BLEND);

  x := 0;
  y := 0;
  w := 800;
  h := 600;
  glColor4f(0.3, 0.5, 0.6, 1);
  glbegin(gl_quads);
   glVertex2f(x, y);
   glVertex2f(x, y+h);
   glVertex2f(x+w, y+h);
   glVertex2f(x+w, y);
  glEnd;

  // Line
  glColor4f(0.9, 0.9, 0.9, 1);
  x := 20;
  y := 5;
  w := 200;
  h := 40;
  glbegin(gl_quads);
   glVertex2f(x, y);
   glVertex2f(x, y+h);
   glVertex2f(x+w, y+h);
   glVertex2f(x+w, y);
  glEnd;

  // Note
  x := 260;
  y := 5;
  w := 200;
  h := 40;
  glbegin(gl_quads);
   glVertex2f(x, y);
   glVertex2f(x, y+h);
   glVertex2f(x+w, y+h);
   glVertex2f(x+w, y);
  glEnd;

  // some borders
  x := 20;
  y := 55;
  w := 760;
  h := 236;
  glColor4f(0.9, 0.9, 0.9, 1);
  glbegin(gl_quads);
   glVertex2f(x, y);
   glVertex2f(x, y+h);
   glVertex2f(x+w, y+h);
   glVertex2f(x+w, y);
  glEnd;

  glColor4f(0, 0, 0, 1);
  glLineWidth(2);
  glBegin(GL_LINE_LOOP);
    glVertex2f(x-1, y-1);
    glVertex2f(x+w+1, y-1);
    glVertex2f(x+w+1, y+h+1);
    glVertex2f(x-1, y+h+1);
  glEnd;

  x := 20;
  y := 305;
  w := 760;
  h := 135;
  glColor4f(0.9, 0.9, 0.9, 1);
  glbegin(gl_quads);
   glVertex2f(x, y);
   glVertex2f(x, y+h);
   glVertex2f(x+w, y+h);
   glVertex2f(x+w, y);
  glEnd;

  glColor4f(0, 0, 0, 1);
  glLineWidth(2);
  glBegin(GL_LINE_LOOP);
    glVertex2f(x-1, y-1);
    glVertex2f(x+w+1, y-1);
    glVertex2f(x+w+1, y+h+1);
    glVertex2f(x-1, y+h+1);
  glEnd;

  x := 20;
  y := 500;
  w := 760;
  h := 40;
  glColor4f(0.9, 0.9, 0.9, 1);
  glbegin(gl_quads);
   glVertex2f(x, y);
   glVertex2f(x, y+h);
   glVertex2f(x+w, y+h);
   glVertex2f(x+w, y);
  glEnd;

  glColor4f(0, 0, 0, 1);
  glLineWidth(2);
  glBegin(GL_LINE_LOOP);
    glVertex2f(x-1, y-1);
    glVertex2f(x+w+1, y-1);
    glVertex2f(x+w+1, y+h+1);
    glVertex2f(x-1, y+h+1);
  glEnd;

  glLineWidth(1);
end;

procedure TScreenEditSub.DrawInfoBar(x, y, w, h: integer);
var
  start, end_:        integer;
  SongStart, SongEnd: integer;
  ww:                 integer;

  pos:                real;
  br:                 real;

  line:               integer;
  numLines:           integer;

begin
  numLines := Length(Lines[0].Line);

  if(numLines=0) then
    Exit;

  SongStart := Lines[0].Line[0].Note[0].Start;
  SongEnd := Lines[0].Line[numLines-1].End_;
  ww := SongEnd - SongStart;

  glColor4f(0, 0, 0, 1);
  glDisable(GL_BLEND);
  glLineWidth(2);
  glBegin(GL_LINE_LOOP);
    glVertex2f(x-1, y-1);
    glVertex2f(x+w+1, y-1);
    glVertex2f(x+w+1, y+h+1);
    glVertex2f(x-1, y+h+1);
  glEnd;

  glColor4f(0.9, 0.9, 0.9, 1);
  glbegin(gl_quads);
   glVertex2f(x, y);
   glVertex2f(x, y+h);
   glVertex2f(x+w, y+h);
   glVertex2f(x+w, y);
  glEnd;


  for line := 0 to numLines - 1 do
  begin
    if (line = Lines[0].Current) and not (PlaySentence or PlaySentenceMidi) then
      glColor4f(0.4, 0.4, 0, 1)
    else
      glColor4f(1, 0.6, 0, 1);


    start := Lines[0].Line[line].Note[0].Start;
    end_ := Lines[0].Line[line].Note[Lines[0].Line[line].HighNote].Start+
      Lines[0].Line[line].Note[Lines[0].Line[line].HighNote].Length;

    pos := (start - SongStart)/ww*w;
    br := (end_-start)/ww*w;

    glbegin(gl_quads);
      glVertex2f(x+pos, y);
      glVertex2f(x+pos, y+h);
      glVertex2f(x+pos+br, y+h);
      glVertex2f(x+pos+br, y);
    glEnd;
  end;

  if(PlaySentence or PlaySentenceMidi) then
  begin
    glColor4f(0, 0, 0, 0.5);
    pos := 0;
    br := (AktBeat - SongStart)/ww*w;
    if (br>w) then
      br := w;
  end else
  begin
    glColor4f(1, 0, 0, 1);
    pos := (Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start - SongStart)/ww*w;
    br := Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length/ww*w;
    if (br<1) then
      br := 1;
  end;

  glEnable(GL_BLEND);
  glbegin(gl_quads);
    glVertex2f(x+pos, y);
    glVertex2f(x+pos, y+h);
    glVertex2f(x+pos+br, y+h);
    glVertex2f(x+pos+br, y);
  glEnd;
  glDisable(GL_BLEND);

  glLineWidth(1);
end;

// from revision 2475
procedure TScreenEditSub.StartVideoPreview;
var
  VideoFile:  IPath;

begin
  if Assigned(fCurrentVideo) then
  begin
    fCurrentVideo.Stop();
    fCurrentVideo := nil;
  end;

  VideoFile := CurrentSong.Path.Append(CurrentSong.Video);
  if (CurrentSong.Video.IsSet) and VideoFile.IsFile then
  begin
    fCurrentVideo := VideoPlayback.Open(VideoFile);
    if (fCurrentVideo <> nil) then
    begin
      fCurrentVideo.Position := CurrentSong.VideoGAP + AudioPlayback.Position;
      fCurrentVideo.Play;
    end;
  end;
end;

procedure TScreenEditSub.StopVideoPreview;
begin
  // Stop video preview of previous song
  if Assigned(fCurrentVideo) then
  begin
    fCurrentVideo.Stop();
    fCurrentVideo := nil;
  end;
end;

constructor TScreenEditSub.Create;
begin
  inherited Create;
  //video
  fCurrentVideo := nil;
  SetLength(Player, 1);
  SetLength(TitleVal, 0);
  SetLength(ArtistVal, 0);
  SetLength(MP3Val, 0);
  SetLength(CoverVal, 0);
  SetLength(BackgroundVal, 0);
  SetLength(BPMVal, 0);
  SetLength(GAPVal, 0);
  SetLength(ToneVal, 0);
  SetLength(DurationVal, 0);
  SetLength(LyricVal, 0);
  //volume
  SetLength(VolumeAudio,0);
  SetLength(VolumeMidi,0);
  SetLength(VolumeClick,0);

  // line
  AddText(40, 11, 1, 30, 0, 0, 0, 'Line:');
  TextSentence := AddText(110, 11, 1, 30, 0, 0, 0, '0 / 0');


  // Note
  AddText(282, 11, 1, 30, 0, 0, 0, 'Note:');
  TextNote := AddText(360, 11, 1, 30, 0, 0, 0, '0 / 0');

  // file info
  //  AddText(30, 65,  0, 24, 0, 0, 0, 'Title:');
  // Title Header
  TitleSlideId := AddSelectSlide(Theme.EditSub.SlideTitle, Titledata, TitleVal);
  SelectsS[TitleSlideId].Text.Align := 0;
  SelectsS[TitleSlideId].Text.X := SelectsS[TitleSlideId].Texture.X + 3;

  //  AddText(30, 90,  0, 24, 0, 0, 0, 'Artist:');
  // Artist Header
  ArtistSlideId := AddSelectSlide(Theme.EditSub.SlideArtist, Artistdata, ArtistVal);
  SelectsS[ArtistSlideId].Text.Align := 0;
  SelectsS[ArtistSlideId].Text.X := SelectsS[ArtistSlideId].Texture.X + 3;

  //AddText(30, 115, 0, 24, 0, 0, 0, 'Mp3:');
  // Artist Header
  MP3SlideId := AddSelectSlide(Theme.EditSub.SlideMP3, MP3data, MP3Val);
  SelectsS[MP3SlideId].Text.Align := 0;
  SelectsS[MP3SlideId].Text.X := SelectsS[MP3SlideId].Texture.X + 3;
  // Cover Header
  CoverSlideId := AddSelectSlide(Theme.EditSub.SlideCover, Coverdata, CoverVal);
  SelectsS[CoverSlideId].Text.Align := 0;
  SelectsS[CoverSlideId].Text.X := SelectsS[CoverSlideId].Texture.X + 3;
  // Background Header
  BackgroundSlideId := AddSelectSlide(Theme.EditSub.SlideBackground, Backgrounddata, BackgroundVal);
  SelectsS[BackgroundSlideId].Text.Align := 0;
  SelectsS[BackgroundSlideId].Text.X := SelectsS[BackgroundSlideId].Texture.X + 3;
  //  AddText(30, 140, 0, 24, 0, 0, 0, 'BPM:');
  // BPM Header
  BPMSlideId := AddSelectSlide(Theme.EditSub.SlideBPM, BPMdata, BPMVal);
  SelectsS[BPMSlideId].Text.Align := 0;
  SelectsS[BPMSlideId].Text.X := SelectsS[BPMSlideId].Texture.X + 3;
  //AddText(30, 165, 0, 24, 0, 0, 0, 'GAP:');
  // GAP Header
  GAPSlideId := AddSelectSlide(Theme.EditSub.SlideGAP, GAPdata, GAPVal);
  SelectsS[GAPSlideId].Text.Align := 0;
  SelectsS[GAPSlideId].Text.X := SelectsS[GAPSlideId].Texture.X + 3;
  // Start Header
  StartSlideId := AddSelectSlide(Theme.EditSub.SlideStart, Startdata, StartVal);
  SelectsS[StartSlideId].Text.Align := 0;
  SelectsS[StartSlideId].Text.X := SelectsS[StartSlideId].Texture.X + 3;
  // Duration Header
  DurationSlideId := AddSelectSlide(Theme.EditSub.SlideDuration, Durationdata, DurationVal);
  SelectsS[DurationSlideId].Text.Align := 0;
  SelectsS[DurationSlideId].Text.X := SelectsS[StartSlideId].Texture.X + 3;
  // Tone Header
  ToneSlideId := AddSelectSlide(Theme.EditSub.SlideTone, Tonedata, ToneVal);
  SelectsS[ToneSlideId].Text.Align := 0;
  SelectsS[ToneSlideId].Text.X := SelectsS[ToneSlideId].Texture.X + 3;
  // Text Header
  LyricSlideId := AddSelectSlide(Theme.EditSub.SlideLyric, Lyricdata, LyricVal);
  SelectsS[LyricSlideId].Text.Align := 0;
  SelectsS[LyricSlideId].Text.X := SelectsS[LyricSlideId].Texture.X + 3;

  VolumeAudioSlideId := AddSelectSlide(Theme.EditSub.SelectVolAudio, VolumeAudioIndex, VolumeAudio);
  VolumeMidiSlideId := AddSelectSlide(Theme.EditSub.SelectVolMidi, VolumeMidiIndex, VolumeMidi);
  VolumeClickSlideId := AddSelectSlide(Theme.EditSub.SelectVolClick, VolumeClickIndex, VolumeClick);

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

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

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

  //TextVideoGap :=  AddText(600, 265,  0, 24, 0, 0, 0, 'e');

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

end;

procedure TScreenEditSub.OnShow;
var
  FileExt: IPath;
  Files: TPathDynArray;
  i: integer;
begin
  inherited;
  // reset video playback engine
  fCurrentVideo := nil;
  AudioPlayback.Stop;
  PlaySentence := false;
  PlaySentenceMidi := false;
  Text[TextDebug].Text := '';
  Log.LogStatus('Initializing', 'TEditScreen.OnShow');
  Lyric := TEditorLyrics.Create;

  ResetSingTemp;
  GoldenRec.KillAll;
//  SetLength(UndoSong, 0);
  SetLength(UndoLines, 0);
  SetLength(UndoStateNote, 0);
  SetLength(Undoheader, 0);

  try
    //Check if File is XML
    FileExt := CurrentSong.FileName.GetExtension;
    if FileExt.ToUTF8 = '.xml' then
      Error := not CurrentSong.LoadXMLSong()
    else
    begin
      // reread header with custom tags
      Error := not CurrentSong.Analyse(true);
      if not Error then
        Error := not CurrentSong.LoadSong;
    end;
  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
  {$IFDEF UseMIDIPort}
    MidiOut := TMidiOutput.Create(nil);
    MidiOut.Open;
  {$ENDIF}
    //    Text[TextTitle].Text :=   CurrentSong.Title;
    // Header Title
    SetLength(TitleVal, 1);
    TitleVal[0] := CurrentSong.Title;
    SlideTitleIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideTitle,TitleSlideId,TitleVal,SlideTitleIndex);
    SelectsS[TitleSlideId].TextOpt[0].Align := 0;
    SelectsS[TitleSlideId].TextOpt[0].X := SelectsS[TitleSlideId].TextureSBG.X + 5;

    //    Text[TextArtist].Text :=  CurrentSong.Artist;
    // Header Artist
    SetLength(ArtistVal, 1);
    ArtistVal[0] := CurrentSong.Artist;
    SlideArtistIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideArtist,ArtistSlideId,ArtistVal,SlideArtistIndex);
    SelectsS[ArtistSlideId].TextOpt[0].Align := 0;
    SelectsS[ArtistSlideId].TextOpt[0].X := SelectsS[ArtistSlideId].TextureSBG.X + 5;

    //Text[TextMp3].Text :=     CurrentSong.Mp3.ToUTF8;
    // Header MP3
    SetLength(MP3Val, 0);
    SetLength(Files, 0);
    SlideMP3Index := -1;
    Songs.FindFilesByExtension(Path(includeTrailingPathDelimiter(CurrentSong.Path.ToNative)), Path('.mp3'), true, Files);
    for i:=0 to high(Files) do
    begin
      SetLength(MP3Val, high(MP3Val)+2);
      MP3Val[i] := filesystem.ExtractFileName(files[i]).ToUTF8;
      if (UTF8CompareText(MP3Val[i],CurrentSong.Mp3.ToUTF8) = 0) then
            SlideMP3Index := i;
    end;
    UpdateSelectSlideOptions(Theme.EditSub.SlideMP3,MP3SlideId,MP3Val,SlideMP3Index);

    // Header Cover
    SetLength(Files, 0);
    SetLength(CoverVal, 0);
    SlideCoverIndex := -1;
    Songs.FindFilesByExtension(Path(includeTrailingPathDelimiter(CurrentSong.Path.ToNative)), Path('.jpg'), true, Files);
    for i:=0 to high(Files) do
    begin
      SetLength(CoverVal, high(CoverVal)+2);
      CoverVal[i] := ExtractFileName(files[i].ToUTF8());
      if UTF8CompareText(CoverVal[i], CurrentSong.Cover.ToUTF8) = 0 then
            SlideCoverIndex := i;
    end;
    if high(Files) < 0 then
    begin
      SetLength(CoverVal, 1);
      CoverVal[0] := CurrentSong.Cover.ToUTF8;
      SlideCoverIndex := 0;
    end;
    UpdateSelectSlideOptions(Theme.EditSub.SlideCover,CoverSlideId,CoverVal,SlideCoverIndex);

    // Header Background
    SetLength(Files, 0);
    SetLength(BackgroundVal, 0);
    SlideBackgroundIndex := -1;
    Songs.FindFilesByExtension(Path(includeTrailingPathDelimiter(CurrentSong.Path.ToNative)), Path('.jpg'), true, Files);
    for i:=0 to high(Files) do
    begin
      SetLength(BackgroundVal, high(BackgroundVal)+2);
      BackgroundVal[i] := ExtractFileName(files[i].ToUTF8());
      if UTF8CompareText(BackgroundVal[i], CurrentSong.Background.ToUTF8) = 0 then
            SlideBackgroundIndex := i;
    end;

    if high(Files) < 0 then
    begin
      SetLength(BackgroundVal, 1);
      BackgroundVal[0] := CurrentSong.Background.ToUTF8;
      SlideBackgroundIndex := 0;
    end;
    UpdateSelectSlideOptions(Theme.EditSub.SlideBackground,BackgroundSlideId,BackgroundVal,SlideBackgroundIndex);

//    SelectsS[BackgroundSlideId].TextOpt[0].Align := 0;

    // Header BPM
    SetLength(BPMVal, 1);
    BPMVal[0] := '';
    SlideBPMIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideBPM,BPMSlideId,BPMVal,SlideBPMIndex);
    SelectsS[BPMSlideId].TextOpt[0].Align := 0;
    SelectsS[BPMSlideId].TextOpt[0].X := SelectsS[BPMSlideId].TextureSBG.X + 5;
    // Header GAP
    SetLength(GAPVal, 1);
    GAPVal[0] := '';
    SlideGAPIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideGAP,GAPSlideId,GAPVal,SlideGAPIndex);
    SelectsS[GAPSlideId].TextOpt[0].Align := 0;
    SelectsS[GAPSlideId].TextOpt[0].X := SelectsS[GAPSlideId].TextureSBG.X + 5;
    // Header Start
    SetLength(StartVal, 1);
    StartVal[0] := '';
    SlideStartIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideStart,StartSlideId,StartVal,SlideStartIndex);
    SelectsS[StartSlideId].TextOpt[0].Align := 0;
    SelectsS[StartSlideId].TextOpt[0].X := SelectsS[StartSlideId].TextureSBG.X + 5;
    // Header Duration
    SetLength(DurationVal, 1);
    DurationVal[0] := '';
    SlideDurationIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideDuration,DurationSlideId,DurationVal,SlideDurationIndex);
    SelectsS[DurationSlideId].TextOpt[0].Align := 0;
    SelectsS[DurationSlideId].TextOpt[0].X := SelectsS[DurationSlideId].TextureSBG.X + 5;
    // Header Tone
    SetLength(ToneVal, 1);
    ToneVal[0] := '';
    SlideDurationIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideTone,ToneSlideId,ToneVal,SlideToneIndex);
    SelectsS[ToneSlideId].TextOpt[0].Align := 0;
    SelectsS[ToneSlideId].TextOpt[0].X := SelectsS[ToneSlideId].TextureSBG.X + 5;
    // Header Tone
    SetLength(LyricVal, 1);
    LyricVal[0] := '';
    SlideLyricIndex := 1;
    UpdateSelectSlideOptions(Theme.EditSub.SlideLyric,LyricSlideId,LyricVal,SlideLyricIndex);
    SelectsS[LyricSlideId].TextOpt[0].Align := 0;
    SelectsS[LyricSlideId].TextOpt[0].X := SelectsS[LyricSlideId].TextureSBG.X + 5;

    // volume slides
    SetLength(VolumeAudio, 0);
    SetLength(VolumeMidi, 0);
    SetLength(VolumeClick, 0);     
    for i:=0 to 100 do
    begin
      SetLength(VolumeAudio, high(VolumeAudio)+2);
      SetLength(VolumeMidi, high(VolumeMidi)+2);
      SetLength(VolumeClick, high(VolumeClick)+2);
      VolumeAudio[i] := inttostr(i);
      VolumeMidi[i] := inttostr(i);
      VolumeClick[i] := inttostr(i);
    end;
    VolumeAudioIndex := 100;
    VolumeMidiIndex := 100;
    VolumeClickIndex := 100;
    UpdateSelectSlideOptions(Theme.EditSub.SelectVolAudio,VolumeAudioSlideId,VolumeAudio,VolumeAudioIndex);
    UpdateSelectSlideOptions(Theme.EditSub.SelectVolMidi,VolumeMidiSlideId,VolumeMidi,VolumeMidiIndex);
    UpdateSelectSlideOptions(Theme.EditSub.SelectVolClick,VolumeClickSlideId,VolumeClick,VolumeClickIndex);

    Lines[0].Current := 0;
    CurrentNote := 0;
    Lines[0].Line[0].Note[0].Color := 2;
    AudioPlayback.Open(CurrentSong.Path.Append(CurrentSong.Mp3));
    //Set Down Music Volume for Better hearability of Midi Sounds
    //Music.SetVolume(0.4);

    Lyric.Clear;
    Lyric.X := 400;
    Lyric.Y := 500;
    Lyric.Align := atCenter;
    Lyric.Size := 42;
    Lyric.ColR := 0;
    Lyric.ColG := 0;
    Lyric.ColB := 0;
    Lyric.ColSR := Skin_FontHighlightR;
    Lyric.ColSG := Skin_FontHighlightG;
    Lyric.ColSB := Skin_FontHighlightB;
    Lyric.AddLine(0);
    Lyric.Selected := 0;

    NotesH := 7;
    NotesW := 4;

  end;

  //Interaction := 0;
  TextEditMode := false;
  TitleEditMode := false;
  ArtistEditMode := false;

  editLenghtText := 0;
  TextPosition := -1;
end;

function TScreenEditSub.Draw: boolean;
var
  i:    integer;
  lastline, note: integer;
  notechange:          boolean;
begin

  glClearColor(1,1,1,1);

  // midi music
  if PlaySentenceMidi then
  begin
   {$IFDEF UseMIDIPort}
    MidiPos := USTime.GetTime - MidiTime + MidiStart;

    // stop the music
    if (MidiPos > MidiStop) then
    begin
      MidiOut.PutShort($B1, $7, floor(1.27*SelectsS[VolumeMidiSlideId].SelectedOption));
      MidiOut.PutShort(MIDI_NOTEOFF or 1, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127);
      PlaySentenceMidi := false;
    end;
  {$ENDIF}

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

    if AktBeat <> LastClick then
    begin
      for i := 0 to Lines[0].Line[Lines[0].Current].HighNote do
        if (Lines[0].Line[Lines[0].Current].Note[i].Start = AktBeat) then
        begin

          LastClick := AktBeat;
          {$IFDEF UseMIDIPort}
          MidiOut.PutShort($B1, $7, floor(1.27*SelectsS[VolumeMidiSlideId].SelectedOption));
          if i > 0 then
            MidiOut.PutShort(MIDI_NOTEOFF or 1, Lines[0].Line[Lines[0].Current].Note[i-1].Tone + 60, 127);
          MidiOut.PutShort($91, Lines[0].Line[Lines[0].Current].Note[i].Tone + 60, 127);
          MidiLastNote := i;
          {$ENDIF}

        end;
    end;
  end; // if PlaySentenceMidi

  // move "cursor"
  if (PlaySentence or PlaySentenceMidi or PlayVideo) then //and Not (PlayNote) then
  begin
    if (PlaySentence or PlayVideo) then
      AktBeat := Floor(GetMidBeat(AudioPlayback.Position - (CurrentSong.GAP) / 1000));
    if PlaySentenceMidi then
      AktBeat := Floor(GetMidBeat(MidiPos - CurrentSong.GAP / 1000));

    lastline := Lines[0].Current;
    repeat              //find current line
    if Lines[0].Line[Lines[0].Current].End_ < AktBeat then
      inc(Lines[0].Current);
    until ((Length(Lines[0].Line) = Lines[0].Current) or (Lines[0].Line[Lines[0].Current].End_ >= AktBeat));
    if Lines[0].Current <> lastline then
    begin
        Lines[0].Line[lastline].Note[CurrentNote].Color := 1;
        Lyric.AddLine(Lines[0].Current);
        Lyric.Selected := 0;
        CurrentNote := 0;
        //showNoteButtons; //prepared for active notes
        GoldenRec.KillAll;
    end;

    for note := CurrentNote to Length(Lines[0].Line[Lines[0].Current].note) - 1 do
      begin
        //note change
        if Lines[0].Line[Lines[0].Current].Note[note].Start < AktBeat then
            begin
              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 1;
              CurrentNote := note;
              Lyric.Selected := CurrentNote;
              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 2;
            end; //if
      end; //for note}
  end; //end move cursor

  // mp3 music
  if (PlaySentence or PlayVideo) then
  begin
    // stop the music
    if (AudioPlayback.Position > PlayStopTime) then
    begin
      AudioPlayback.Stop;
      PlaySentence := false;
      PlayVideo := false;
      StopVideoPreview;
    end;

    // click
    if (Click) and (PlaySentence) then
    begin
      //AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60);
      AktBeat := Floor(GetMidBeat(AudioPlayback.Position - CurrentSong.GAP / 1000));
      Text[TextDebug].Text := IntToStr(AktBeat);
      if AktBeat <> LastClick then
      begin
        for i := 0 to Lines[0].Line[Lines[0].Current].HighNote do
          if (Lines[0].Line[Lines[0].Current].Note[i].Start = AktBeat) then
          begin
            SoundLib.Click.Volume := SelectsS[VolumeClickSlideId].SelectedOption / 100;
            AudioPlayback.PlaySound( SoundLib.Click );
            LastClick := AktBeat;
          end;
      end;
    end; // click
  end; // if PlaySentence


  Text[TextSentence].Text := IntToStr(Lines[0].Current + 1) + ' / ' + IntToStr(Lines[0].Number);
  Text[TextNote].Text := IntToStr(CurrentNote + 1) + ' / ' + IntToStr(Lines[0].Line[Lines[0].Current].HighNote + 1);

  // Song info
  //Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4);
  BPMVal[0] := FloatToStr(CurrentSong.BPM[0].BPM / 4);
  SelectsS[BPMSlideId].TextOpt[0].Text := BPMVal[0];
  //Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
  GAPVal[0] := FloatToStr(CurrentSong.GAP);
  SelectsS[GAPSlideId].TextOpt[0].Text := GAPVal[0];

  //Error reading Variables when no Song is loaded
  if not (Error or TitleEditMode or TextEditMode) then
  begin
    // Note info
    //Text[TextNStart].Text :=    IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
    StartVal[0] := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Start);
    SelectsS[StartSlideId].TextOpt[0].Text := StartVal[0];
    //Text[TextNLength].Text :=  IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
    DurationVal[0] := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Length);
    SelectsS[DurationSlideId].TextOpt[0].Text := DurationVal[0];
    //Text[TextNTon].Text :=      IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' ( ' + GetNoteName(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' )';
    ToneVal[0] := IntToStr(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' ( ' + GetNoteName(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Tone) + ' )';
    SelectsS[ToneSlideId].TextOpt[0].Text := ToneVal[0];
    //Text[TextNText].Text :=              Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text;
    LyricVal[0] := Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text;
    SelectsS[LyricSlideId].TextOpt[0].Text := LyricVal[0];
  end;

  // Text Edit Mode
  if TextEditMode or TitleEditMode or ArtistEditMode then
  begin
    if TextPosition >= 0 then
    SelectsS[CurrentSlideId].TextOpt[0].Text :=
      UTF8Copy(CurrentEditText, 1, TextPosition) + '|' + UTF8Copy(CurrentEditText, TextPosition+1, LengthUTF8(CurrentEditText)-TextPosition);
    editLenghtText := LengthUTF8(SelectsS[CurrentSlideId].TextOpt[0].Text);
  end;

  // draw static menu
  DrawBG;
  DrawStatics;
  DrawInfoBar(20, 460, 760, 20);
  //inherited Draw;
  DrawFG;
  // draw notes
  SingDrawNoteLines(20, 305, 780, 15);
  //Error Drawing when no Song is loaded
  if not Error then
  begin
    SingDrawBeatDelimeters(40, 305, 760, 0);
    EditDrawLine(40, 410, 760, 0, 15);
  end;
  GoldenRec.SpawnRec;
  // draw text
  Lyric.Draw;
  //video
  if Assigned(fCurrentVideo) then
  begin
      fCurrentVideo.GetFrame(CurrentSong.VideoGAP + AudioPlayback.Position);
      fCurrentVideo.SetScreen(1);
      fCurrentVideo.Alpha := 1;
      fCurrentVideo.SetScreenPosition(510, 60, 1);
      fCurrentVideo.Width := 250;
      fCurrentVideo.Height := 205;
      fCurrentVideo.ReflectionSpacing := 1;
      fCurrentVideo.AspectCorrection := acoCrop;

      fCurrentVideo.Draw;
  end;



  Result := true;
end;

procedure TScreenEditSub.OnHide;
begin
  {$IFDEF UseMIDIPort}
  MidiOut.Close;
  MidiOut.Free;
  {$ENDIF}
  Lyric.Free;
  //Music.SetVolume(1.0);
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;

end.