;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Puzzle of Mystralia ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Code : SPH(2023) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;é
Global win, LMB, RMB, MMB, OldMouseX, OldMouseY
#dst=1
InitSprite() 
InitMouse() 
InitKeyboard()
InitSound()
UseJPEGImageDecoder()


win=OpenWindow(#PB_Any, 0, 0, 0, 0, "Puzzle of Mystralia", #PB_Window_Maximize |  #PB_Window_BorderLess )
scr_w=WindowWidth(win)
scr_h=WindowHeight(win)
OpenWindowedScreen (WindowID(win),0 , 0, scr_w, scr_h, 0, 0, 0, #PB_Screen_SmartSynchronization)
ShowCursor_(0) ; CRISOT - On cache le curseur.
ShowCursor_(0) ; CRISOT - On cache le curseur.

;{
Procedure CrisotResetMouseDelta()
  OldMouseX=WindowMouseX(win)
  OldMouseY=WindowMouseY(win)
EndProcedure

Procedure CrisotMouseDeltaX()
  DeltaMouseX=WindowMouseX(win)-OldMouseX
  OldMouseX=WindowMouseX(win)
  ProcedureReturn DeltaMouseX
EndProcedure

Procedure CrisotMouseDeltaY()
  DeltaMouseY=WindowMouseY(win)-OldMouseY
  OldMouseY=WindowMouseY(win)
  ProcedureReturn DeltaMouseY
EndProcedure

Procedure CrisotMouseButton()
  Repeat
    Event = WindowEvent()
    Select Event
      Case #WM_LBUTTONDOWN         ; API Windows
        LMB=#True
      Case #PB_Event_LeftClick   ; bricolage - #WM_LBUTTONUP plante
        LMB=#False
      Case #WM_RBUTTONDOWN         ; API Windows
        RMB=#True
      Case #PB_Event_RightClick   ; bricolage - #WM_RBUTTONUP plante
        RMB=#False
      Case #WM_MBUTTONDOWN         ; API Windows
        MMB=#True
      Case #WM_MBUTTONUP         ; API Windows
        MMB=#False
    EndSelect
  Until Event=0
EndProcedure

Procedure CrisotLeftMouseButton()   
  CrisotMouseButton()
  ProcedureReturn LMB
EndProcedure

Procedure CrisotRightMouseButton()
  CrisotMouseButton()
  ProcedureReturn RMB
EndProcedure

Procedure CrisotMiddleMouseButton()
  CrisotMouseButton()
  ProcedureReturn MMB
EndProcedure
;}
;- ########

;- Sprites
a$="images/"
LoadSprite(0,a$+"souris.bmp")
LoadSprite(1,a$+"pieceN.bmp")
LoadSprite(2,a$+"pieceB.bmp")
LoadSprite(10,a$+"angle1.bmp")
LoadSprite(11,a$+"angle2.bmp")
LoadSprite(12,a$+"angle3.bmp")
LoadSprite(20,a$+"angleb1.bmp")
LoadSprite(21,a$+"angleb2.bmp")
LoadSprite(22,a$+"angleb3.bmp")
LoadSprite(30,a$+"ligneH.bmp")
LoadSprite(40,a$+"ligneD1.bmp")
LoadSprite(50,a$+"ligneD2.bmp")
LoadSprite(60,a$+"light.bmp")
LoadSprite(70,a$+"circle.bmp")

LoadSound(0,"sfx\1.wav")
LoadSound(1,"sfx\2.wav")

LoadFont(1, "Times New Roman", 30)
LoadFont(2, "Times New Roman", 10)

max_x=14
max_y=9
puzzle_x=0
reset=0

;;;;;;;;;;
;;;;;;;;;;
puzzle_x2=0
Repeat
  puzzle_x2+1
Until ReadFile(#dst, "levels/puzzle_"+Str(puzzle_x2))=0
;Debug puzzle_x2
;;;;;;;;;;
;;;;;;;;;;

generik: ;-generik
b$="Continue"
c$="Reset"

LoadSprite(100,"images/1.jpg")
LoadSprite(101,"images/pom.bmp")

If ReadFile(#dst, "levels/level")
  puzzle_x=ReadByte(#dst)
  CloseFile(#dst)
EndIf

Repeat
  mx=WindowMouseX(win)	; CRISOT
  my=WindowMouseY(win)  ; CRISOT
  
  ;Mb_Right=MouseButton(#PB_MouseButton_Right) ; CRISOT
  ;Mb_Left=MouseButton(#PB_MouseButton_Left)	; CRISOT
  Mb_Right=CrisotRightMouseButton()				; CRISOT
  Mb_Left=CrisotLeftMouseButton()         ; CRISOT
  While WindowEvent() : Wend
  
  ;ClearScreen(RGB(0,0,0))
  DisplaySprite(100,(scr_w-1920)/2,(scr_h-1080)/2)
  DisplayTransparentSprite(101,(scr_w/2)-SpriteWidth(101)/2,scr_h/2-50-SpriteHeight(101))
  
  StartDrawing(ScreenOutput()) : DrawingMode(#PB_2DDrawing_Transparent)
  DrawingFont(FontID(2))
  DrawText(22,scr_h-30,"v1.2 - SPH(2023)",RGB(0,0,0))
  DrawText(21,scr_h-31,"v1.2 - SPH(2023)",RGB(100,100,100))
  DrawingFont(FontID(1))
  DrawText(22,18,Str(puzzle_x+1)+" / "+Str(puzzle_x2),RGB(0,0,0))
  DrawText(20,16,Str(puzzle_x+1)+" / "+Str(puzzle_x2),RGB(255,255,255))
  ; b$ 
  DrawingFont(FontID(1))
  x=TextWidth(b$)/2
  y=scr_h/2+50
  DrawText((scr_w/2)-x+2,y+2,b$,RGB(0,0,0))
  If mx>(scr_w/2)-x And mx<(scr_w/2)+x And my>y And my(scr_w/2)-x And mx<(scr_w/2)+x And my>y And my0 ;And 1=0
        If piece(i-1,u)=1
          LineXY((u%2)*75+i*150-dk_x,u*150-1-dk_y,(u%2)*75+(i-1)*150-dk_x,u*150-1-dk_y,RGB(100,100,100)) 
          LineXY((u%2)*75+i*150-dk_x,u*150+1-dk_y,(u%2)*75+(i-1)*150-dk_x,u*150+1-dk_y,RGB(100,100,100)) 
          LineXY((u%2)*75+i*150-dk_x,u*150-dk_y,(u%2)*75+(i-1)*150-dk_x,u*150-dk_y,RGB(200,200,200)) 
        EndIf
      EndIf
      ;;;;;;;;; vers le bas a droite
      If i>0 And i(u%2)*75+i*150-dk_x-50 And mx<(u%2)*75+i*150-dk_x+50
          If my>u*150-dk_y-50 And my0; fleches
              DisplayTransparentSprite(70,(u%2)*75+i*150-dk_x-58,u*150-dk_y-58,120)
            EndIf
          EndIf
        EndIf
      Next
    Next
    
                  
  If Mb_Left=1 And mb=0 And pause=0
    mb=1
    For i=0 To max_x
      For u=0 To max_y
        If mx>(u%2)*75+i*150-dk_x-50 And mx<(u%2)*75+i*150-dk_x+50
          If my>u*150-dk_y-50 And my0; fleches
                zz=tableau(i,u)
                PlaySound(0) : SetSoundFrequency(0,12000)
                ; debug "i === "+Str(i)+" --- u === "+Str(u)+" --- z === "+Str(zz)
                For r=1 To piece_z(0)
                  ; debug "i = "+Str(piece_x(r))+" - u ="+Str(piece_y(r))+" - z ="+Str(piece_z(r))
                Next
                ; debug "zz = "+Str(zz)
                ;;;
                For rap=1 To piece_z(0)
                  If piece_x(rap)=i And piece_y(rap)=u
                    ; debug "rap = "+Str(rap)
                    piece_x(rap)=0
                    piece_y(rap)=0
                    piece_z(rap)=0
                    tableau(i,u)=0
                    ; debug "i = "+Str(i)+" - u ="+Str(u)
                    Goto ok;Break
                  EndIf
                Next
                ; debug "ERROR 1" : Beep_(400,500) : End
                ok:
                avoir=1
                Swap piece_x(rap),piece_x(1)
                Swap piece_y(rap),piece_y(1)
                Swap piece_z(rap),piece_z(1)
                ; debug "======"
                For r=1 To piece_z(0)
                  ; debug "i = "+Str(piece_x(r))+" - u ="+Str(piece_y(r))+" - z ="+Str(piece_z(r))
                Next
                ; debug "================"
                ; debug "================"
              EndIf
              
            Else 
              If piece(i,u)=1; point blanc
                             ; debug "AVOIR = 1 !!!!!!!!!!!!!!!!!!"
                PlaySound(0) : SetSoundFrequency(0,12000)
                zz2=tableau(i,u)
                tableau(i,u)=zz
                
                piece_x(1)=i
                piece_y(1)=u
                piece_z(1)=zz
                
                If zz2=0
                  avoir=0
                  ; debug "Goto ok3 !!!!!!!"
                  Goto ok3
                EndIf
                
                For rap2=2 To piece_z(0)
                  If piece_x(rap2)=i And piece_y(rap2)=u
                    ; debug "rap2 = "+Str(rap2)
                    ; debug "Trouvé sur  : ( i = "+Str(i)+" - u ="+Str(u)+" )"
                    Goto ok2;Break
                  EndIf
                Next
                ; debug "ERROR 2" : Beep_(400,500) : End
                ok2:
                Swap piece_x(rap2),piece_x(1)
                Swap piece_y(rap2),piece_y(1)
                Swap piece_z(rap2),piece_z(1)
                zz=zz2 
              EndIf
            EndIf
            ok3:
            
          EndIf
        EndIf
      Next
    Next
  EndIf
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  light+light2
  If light>30
    light2*-1
    light+light2
  EndIf
  If light<5
    light2*-1
    light+light2
  EndIf
  
  
  ;- affichage pieces et liens
  
  ;{
  ;;;;;;;;;;;;;;;;;;;;;
  Dim lum.b(piece_z(0)*2+2)
  Dim ok.b(piece_z(0))
  
  For u=0 To 1
    For i=1 To piece_z(0)
      ;;;
      cmb=0
      cmb2=0
      ii=piece_z(i)&1
      If tableau(piece_x(i),piece_y(i))&1
        lumiere=12
        cmb+1
        If tableau(piece_x(i)+1-(piece_y(i)+1)%2,piece_y(i)-1)&8
          lumiere=22
          lum(i*2+u)=1
          cmb2+1
          If u=0
            DisplayTransparentSprite(50,piece_y(i)%2*75+piece_x(i)*150-dk_x-7,piece_y(i)*150-dk_y-150,200)
          EndIf
        EndIf
        If u=1
          DisplayTransparentSprite(lumiere,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii),piece_y(i)*150-dk_y+dk_y(ii))
          If lum(i*2+u)=1 And lumiere=22
            DisplayTransparentSprite(60,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii)-12,piece_y(i)*150-dk_y+dk_y(ii)-12,light)
          EndIf
        EndIf
      EndIf
      ;;;
      ii=piece_z(i)&2
      If tableau(piece_x(i),piece_y(i))&2
        lumiere=10
        cmb+1
        If tableau(piece_x(i)+1,piece_y(i))&16
          lumiere=20
          lum(i*2+u)=1
          cmb2+1
          If u=0
            DisplayTransparentSprite(30,piece_y(i)%2*75+piece_x(i)*150-dk_x,piece_y(i)*150-dk_y-10,200)
          EndIf
        EndIf
        If u=1
          DisplayTransparentSprite(lumiere,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii),piece_y(i)*150-dk_y+dk_y(ii))
          If lum(i*2+u)=1 And lumiere=20
            DisplayTransparentSprite(60,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii)-8,piece_y(i)*150-dk_y+dk_y(ii)-12,light)
          EndIf
        EndIf
      EndIf
      ;;;
      ii=piece_z(i)&4
      If tableau(piece_x(i),piece_y(i))&4
        lumiere=11
        cmb+1
        If tableau(piece_x(i)+1-(piece_y(i)+1)%2,piece_y(i)+1)&32
          lumiere=21
          lum(i*2+u)=1
          cmb2+1
          If u=0
            DisplayTransparentSprite(40,piece_y(i)%2*75+piece_x(i)*150-dk_x-6,piece_y(i)*150-dk_y,200)
          EndIf
        EndIf
        If u=1
          DisplayTransparentSprite(lumiere,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii),piece_y(i)*150-dk_y+dk_y(ii))
          If lum(i*2+u)=1 And lumiere=21
            DisplayTransparentSprite(60,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii)-12,piece_y(i)*150-dk_y+dk_y(ii)-10,light)
          EndIf
        EndIf
      EndIf
      ;;;      
      ii=piece_z(i)&32
      If tableau(piece_x(i),piece_y(i))&32
        lumiere=11
        cmb+1
        If tableau(piece_x(i)-(piece_y(i)+1)%2,piece_y(i)-1)&4
          lumiere=21
          lum(i*2+u)=1
          cmb2+1
        EndIf
        If u=1
          DisplayTransparentSprite(lumiere,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii),piece_y(i)*150-dk_y+dk_y(ii))
          If lum(i*2+u)=1 And lumiere=21
            DisplayTransparentSprite(60,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii)-12,piece_y(i)*150-dk_y+dk_y(ii)-12,light)
          EndIf
        EndIf
      EndIf
      ;;;
      ii=piece_z(i)&8
      If tableau(piece_x(i),piece_y(i))&8
        lumiere=12
        cmb+1
        If tableau(piece_x(i)-0-(piece_y(i)+1)%2,piece_y(i)+1)&1
          lumiere=22
          lum(i*2+u)=1
          cmb2+1
        EndIf
        If u=1
          DisplayTransparentSprite(lumiere,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii),piece_y(i)*150-dk_y+dk_y(ii))
          If lum(i*2+u)=1 And lumiere=22
            DisplayTransparentSprite(60,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii)-14,piece_y(i)*150-dk_y+dk_y(ii)-10,light)
          EndIf
        EndIf
      EndIf
      ;;;
      ii=piece_z(i)&16
      
      If tableau(piece_x(i),piece_y(i))&16
        lumiere=10
        cmb+1
        If tableau(piece_x(i)-1,piece_y(i))&2
          lumiere=20
          lum(i*2+u)=1
          cmb2+1
        EndIf
        If u=1
          DisplayTransparentSprite(lumiere,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii),piece_y(i)*150-dk_y+dk_y(ii))
          If lum(i*2+u)=1 And lumiere=20
            DisplayTransparentSprite(60,piece_y(i)%2*75+piece_x(i)*150-dk_x+dk_x(ii)-12,piece_y(i)*150-dk_y+dk_y(ii)-12,light)
          EndIf
        EndIf
      EndIf
      
      oks:  
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      If u=1 And piece_z(i)<>0
        If cmb=cmb2 And cmb>0
          ok(i)=1
          blanc=2
        Else
          blanc=1
        EndIf
        DisplayTransparentSprite(blanc,piece_y(i)%2*75+piece_x(i)*150-dk_x-44,piece_y(i)*150-dk_y-44)
      EndIf
    Next
  Next
  ;}
  
 
  uu=0
  For i=1 To piece_z(0)
    uu+ok(i)
  Next
  ;
  ;;;;;;;;;;   
  ;-avoir=1
  If avoir=1
    n=12
    u=1
    For i=1 To 6
      If zz&u
        DisplayTransparentSprite(n,mx+dk_x(u),my+dk_y(u))
      EndIf
      n+1
      If n>12
        n=10
      EndIf
      u*2
    Next
    DisplayTransparentSprite(1,mx-44,my-44)
  EndIf
  
  StartDrawing(ScreenOutput()) : DrawingMode(#PB_2DDrawing_Transparent)
  DrawingFont(FontID(2))
  DrawText(22,scr_h-30,"v1.2 - SPH(2023)",RGB(0,0,0))
  DrawText(21,scr_h-31,"v1.2 - SPH(2023)",RGB(100,100,100))
  DrawingFont(FontID(1))
  DrawText(22,18,Str(puzzle_x+1)+" / "+Str(puzzle_x2),RGB(0,0,0))
  DrawText(20,16,Str(puzzle_x+1)+" / "+Str(puzzle_x2),RGB(255,255,255))
  StopDrawing()
  
  DisplayTransparentSprite(0,mx,my)
  FlipBuffers()
  Delay(1)  
  
  If uu=piece_z(0) And pause=0 And avoir=0
    pause=1
    PlaySound(1)
    time=ElapsedMilliseconds()
  EndIf
  ;;;;;;;

  If pause=1 And Abs(ElapsedMilliseconds()-time)>2000
    pause=0
    puzzle_x+1
    If puzzle_x=puzzle_x2
      Goto fin
    EndIf
    ;-SAVE
    If CreateFile(#dst, "levels/level")  ; Ouvre un fichier existant ou en crée un nouveau s'il n'existait pas
      WriteLong(#dst,puzzle_x)
      CloseFile(#dst)
    EndIf
    Goto debut
  EndIf
Until KeyboardPushed(#PB_Key_Escape)
End
    puzzle_x+1
    PlaySound(1)
    Delay(200)
    Goto debut


fin:
a$="Congratulations, you have formed all "+Str(puzzle_x2)+" puzzles"
b$="= EXIT ="
LoadSprite(100,"images/1.jpg")
LoadSprite(101,"images/pom.bmp")

Repeat
  mx=WindowMouseX(win)	; CRISOT
  my=WindowMouseY(win)  ; CRISOT
  
  ;Mb_Right=MouseButton(#PB_MouseButton_Right) ; CRISOT
  ;Mb_Left=MouseButton(#PB_MouseButton_Left)	; CRISOT
  Mb_Right=CrisotRightMouseButton()				; CRISOT
  Mb_Left=CrisotLeftMouseButton()         ; CRISOT
  While WindowEvent() : Wend
  
  ;ClearScreen(RGB(0,0,0))
  DisplaySprite(100,(scr_w-1920)/2,(scr_h-1080)/2)
  DisplayTransparentSprite(101,(scr_w/2)-SpriteWidth(101)/2,scr_h/2-50-SpriteHeight(101))
  StartDrawing(ScreenOutput()) : DrawingMode(#PB_2DDrawing_Transparent)
  ; a$
  DrawingFont(FontID(1))
  x=TextWidth(a$)/2
  
  DrawText((scr_w/2)-x+2,scr_h/2+2-20,a$,RGB(0,0,0))
  DrawText((scr_w/2)-x,scr_h/2-20,a$,RGB(255,255,255))
  
  ; b$ 
  DrawingFont(FontID(1))
  x=TextWidth(b$)/2
  y=scr_h/2+110
  
  DrawText((scr_w/2)-x+2,y+2,b$,RGB(0,0,0))
  If mx>(scr_w/2)-x And mx<(scr_w/2)+x And my>y And my