EnableExplicit

Enumeration
  #File

  #Mainform

  #MainMenu
  #New
  #Open
  #Save
  #SaveAs
  #Quit

  #Editor
  #StatusBar
EndEnumeration

Global StyleWindows.l=#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget
Global SciPos.l, SciLine.l, SciCol.l, SciIndent.l, SciFile.s, SciText.s
Global Result.l, FileLenght.l, *MemoryID.l

;CallBack qui recevra les evenements emis par le gadget Scintilla
;*scinotify pointe vers une structure comportant les informations sur l'évènement:
;Voir le bas de cette page http://www.scintilla.org/ScintillaDoc.html
;
;Cette procedure va permettre de connaitre la position courante du curseur
;et de se positionner correctement apres avoir actionner la touche Entrée
ProcedureDLL ScintillaCallBack(Gadget, *scinotify.SCNotification)
  ;La touche Entrée est utilisée
  If *scinotify\ch=13
   
    ;Mise en place dans la nouvelle ligne de l'indentation de la ligne précédente
    ScintillaSendMessage(Gadget, #SCI_SETLINEINDENTATION, SciLIne+1, SciIndent)
   
    ;Positionnement du curseur d'edition sur la nouvelle ligne
    ;Si pas d'indentation alors on ajoute 2 (ça fait bricolage mais je n'ai pas trouvé mieux)
    If SciIndent=0
      SciPos=SciPos+2
    EndIf
   
    ;Positionnement du curseur
    ScintillaSendMessage(Gadget, #SCI_GOTOPOS, SciPos+SciIndent)

  EndIf

  ;Determination de la position à l'intérieur de la chaine scintilla
  SciPos = ScintillaSendMessage(Gadget, #SCI_GETANCHOR)

  ;Determination de la ligne en cours
  SciLine = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, SciPos)

  ;Determination de la colonne en cours
  SciCol = ScintillaSendMessage(Gadget, #SCI_GETCOLUMN, SciPos)

  ;Determination de l'indentation
  SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)

  ;Affichage du numéro de ligne/colonne dans la barre de status
; StatusBarText(#StatusBar,0,"Line : " +Str(SciLine+1)+ "  Col : "+Str(SciCol+1), #PB_StatusBar_Center)
EndProcedure

Procedure SetScintillaProperties(Gadget)

  ;Chargement du dictionnaire HTML
  ScintillaSendMessage(Gadget, #SCI_SETLEXER, #SCLEX_HTML)

  ;Style par defaut du gadget scintilla
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_DEFAULT, $000000)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_DEFAULT, $EAFEFE)
  ScintillaSendMessage(Gadget, #SCI_STYLESETFONT,#STYLE_DEFAULT,@"Verdana")
  ScintillaSendMessage(Gadget, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 12)
  ;ScintillaSendMessage(gadget, #SCI_CLEARALL)
   
  ;Affichage de la colone de numérotation des lignes
  ScintillaSendMessage(Gadget, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER) ;
  ScintillaSendMessage(Gadget, #SCI_SETMARGINWIDTHN, 0, 40)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #STYLE_LINENUMBER, $D4D4D4)
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_LINENUMBER, $10FFFF)

  ;Margin Mask Folder
  ScintillaSendMessage(Gadget, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)
  ScintillaSendMessage(Gadget, #SCI_SETMARGINWIDTHN, 2, 15)

  ;Affichage et couleur de la ligne active
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEVISIBLE, #True)
  ScintillaSendMessage(Gadget, #SCI_SETCARETLINEBACK, $C4FBFA)

  ;Les tabulations sont remplacées par des espaces
  ScintillaSendMessage(Gadget, #SCI_SETUSETABS, #False)

  ;Nombre d'espaces pour une tabulation
  ScintillaSendMessage(Gadget, #SCI_SETINDENT, 4)

  ;Affichage du guide d'indentation et affectatoin d'une couleur
  ScintillaSendMessage(Gadget, #SCI_SETINDENTATIONGUIDES, #SC_IV_LOOKFORWARD)
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #STYLE_INDENTGUIDE, $0605F7)

  ;coloration syntaxique (Prefixe #SCE_H pour les attribut du lexer HTML)

  ;Texte par defaut
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_DEFAULT, $000000)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_DEFAULT, $EAFEFE)

  ;Balises HTML
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_TAG, $0605F9)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_TAG, $EAFEFE)

  ;Balises inconnues
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_TAGUNKNOWN, $949494)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_TAGUNKNOWN, $EAFEFE)

  ;Attributs
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_ATTRIBUTE, $E01A1F)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_ATTRIBUTE, $EAFEFE)

  ;Attributs inconnus
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_ATTRIBUTEUNKNOWN, $505000)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_ATTRIBUTEUNKNOWN, $EAFEFE)

  ;Chiffres
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_NUMBER, $0005FF)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_NUMBER, $EAFEFE)

  ;Texte entres guillemets
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_DOUBLESTRING, $787878)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_DOUBLESTRING, $EAFEFE)

  ;Textes entres simples quotes
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_SINGLESTRING, $787878)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_SINGLESTRING, $EAFEFE)

  ;Autres balises
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_OTHER, $AE0050)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_OTHER, $EAFEFE)

  ;Commentaires
  ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #SCE_H_COMMENT, $8CEE73)
  ScintillaSendMessage(Gadget, #SCI_STYLESETBACK, #SCE_H_COMMENT, $EAFEFE)

EndProcedure

;Affichage de la fenetre principale de l'application
Procedure MainFormShow()
  OpenWindow(#MainForm,  0,  0, 800, 600, "HTML Editor", StyleWindows)

  ;Evite le scintillement du Scintilla gadget lors du redimentionnement de la fenetre
  SmartWindowRefresh(#Mainform, #True)

  ;Menu de l'application
  CreateMenu(#mainmenu,WindowID(#MainForm))
  MenuTitle("Fichier")
  MenuItem(#New,"Nouveau")
  MenuItem(#Open,"Ouvrir")
  MenuItem(#Save,"Enregistre")
  MenuItem(#SaveAs,"Enregistrer Sous")
  MenuBar()
  MenuItem(#Quit,"Quitter")

  ;@ScintillaCallBack() correspond à l'adresse de la procédure
  ;qui recevra les évènements émis par le contrôle.
  ScintillaGadget(#Editor, 10, 40, 790, 590, @ScintillaCallBack())
   
  CreateStatusBar(#StatusBar,WindowID(#Mainform))
  AddStatusBarField(150)
  AddStatusBarField(450)


  RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)

  ;Affectation des touches de racourcis à aucun évènement menu
  ;tant qu'elles ne servent à rien afin d'éviter l'insertion des caracteres spéciaux
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_B, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_G, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_E, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_R, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_O, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_P, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_Q, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_S, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_F, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_H, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_K, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_W, 0)
  AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control+#PB_Shortcut_N, 0)

  StatusBarText(#StatusBar,1,"Nouveau document")
  SetActiveGadget(#editor)
EndProcedure

;Redimensionnement de la fenetre principale
Procedure MainFormResize()
  ResizeGadget(#Editor, #PB_Ignore, #PB_Ignore, WindowWidth(#MainForm)-30, WindowHeight(#Mainform)-100)
EndProcedure

;Nouveau document
Procedure NewFile()
  ScintillaSendMessage(#Editor, #SCI_SETTEXT, 0, @"")
  StatusBarText(#StatusBar,1,"Nouveau document")
EndProcedure

;Ouverture d'un fichier
Procedure LoadFile()
  SciFile=OpenFileRequester("Ouvrir un fichier", "", "html (*.html)|*.html|All files (*.*)|*.*", 0)
  If SciFile
    StatusBarText(#StatusBar,1,SciFile)
    If ReadFile(#File, SciFile)
      FileLenght = Lof(#file)
      *MemoryID = AllocateMemory(FileLenght)
      If *MemoryID
        ReadData(#File, *MemoryID, FileLenght)
        ScintillaSendMessage(#Editor, #SCI_SETTEXT, 0, *MemoryID)
        FreeMemory(*MemoryID)
      EndIf
      CloseFile(#File)
    EndIf
  EndIf
EndProcedure

;Sauvegarde d'un fichier sous
Procedure SaveFileAs()
  SciFile=OpenFileRequester("Sauvegarder un  fichier sous", "", "html (*.html)|*.html|All files (*.*)|*.*", 0)
  If SciFile
    StatusBarText(#StatusBar,1,SciFile)
    If CreateFile(#File, SciFile)
     FileLenght = ScintillaSendMessage(#Editor, #SCI_GETLENGTH)+1
     *MemoryID = AllocateMemory(FileLenght)
     If *MemoryID
       ScintillaSendMessage(#Editor, #SCI_GETTEXT, FileLenght, *MemoryID)
       WriteData(#File, *MemoryID, FileLenght)
       FreeMemory(*MemoryID)
     EndIf
     CloseFile(#File)
    EndIf
  EndIf
EndProcedure

;Sauvegarde d'un fichier
Procedure SaveFile()
  If SciFile<>""
  If CreateFile(#File, SciFile)
    FileLenght = ScintillaSendMessage(#Editor, #SCI_GETLENGTH)+1
    *MemoryID = AllocateMemory(FileLenght)
    If *MemoryID
      ScintillaSendMessage(#Editor, #SCI_GETTEXT, FileLenght, *MemoryID)
      WriteData(#File, *MemoryID, FileLenght)
      FreeMemory(*MemoryID)
    EndIf
    CloseFile(#File)
  EndIf
Else
  SaveFileAs()
EndIf
EndProcedure
InitScintillaStaticFull()
;Debut du traitement
MainFormShow()
SetScintillaProperties(#Editor)

Repeat     
  Select WaitWindowEvent()
    Case #PB_Event_Menu
      Select EventMenu()
        Case #new
          NewFile()
        Case #Open
          LoadFile()
        Case #Save
          SaveFile()
        Case #SaveAs
          SaveFileAs()
        Case #Quit
          End
      EndSelect
     
    Case #PB_Event_Gadget
      Select EventGadget()

      EndSelect
     
    Case #PB_Event_SizeWindow
      MainFormResize()
     
    Case #PB_Event_CloseWindow
      End
     
  EndSelect
ForEver

; IDE Options = PureBasic 4.61 Beta 1 (Windows - x86)
; CursorPosition = 254
; FirstLine = 252
; Folding = --
; EnableXP
; CompileSourceDirectory