Attribute VB_Name = "modul_Calaym_TearDown"
' Copyright (C) 2002-2010 Jan Vorel
' 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; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

' If you have any questions, suggestions or bug reports about this product,
' contact me: info@ctuser.net; Do not contact me about general B.A.S.I.C.
' language or A.P.I. issues

Option Explicit
Option Base 0

#Const ShowRegKeyStuff = False
#Const ShowMoreTTInfo = False
#Const NewKeyMode = True
#Const AnimateReadDir = True

Public AnimateForTearCountX As Long
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long

#If NewKeyMode Then
  Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
  Public xKeyReg(KbdCountX_Minus_KbdSplitN) As Long
  
  Public RGK_xOldKey As Long
  Public RGK_xOldKeyTime As Long
  Public RGK_xOldKeyTimeWait As Long
  Public Const RGK_xOldKeyTimeWaitLong As Long = 250& '750&
  Public Const RGK_xOldKeyTimeWaitShort As Long = 40& '150&
  #End If

'Private Const ctSSLayer_MaxIDsX As Long = ctSSLayer_MaxIDs - 1&
Public ctSSLayer_MaxIDs As Long
Private ctSSLayer_MaxIDsX As Long

Public Tear_Type() As Long
Private Tear_STime() As Long ' lasttime
Private Tear_Delay() As Long
Public Tear_WasVolume() As Single
Public Tear_Volume() As Single
Private Tear_Special() As Long
Private Tear_ShouldVolume() As Long
Public Tear_StepT() As Long
Public SongPointer() As Long
Private Const MaxWaitID As Long = 3&

Public AllTears_Types(MaxWaitID) As Long
Public AllTears_TypesCount As Long
Public AllTears_IDs As String
Public CurrentSongID As Long



Public Sub Tear_WaitFor(ByRef WaitForDesiredType As Long)
  Dim xLong1 As Long
  
  Select Case WaitForDesiredType
    Case Is < 0& '-1& 'waitforall
      Call Tear_StartDropping(-1&, 0&, 0&, 0&, SimpleFadingTotalTime, 0&)
    Case 1& To MaxWaitID ' wait for midis / cdda /
      If Not AllTears_Types(WaitForDesiredType) = 0& Or AllTears_TypesCount = ctSSLayer_MaxIDs Then
        Call Tear_StartDropping(-1&, 0&, 0&, 0&, SimpleFadingTotalTime, 0&)
        End If
    End Select
  Do
    Call TearDown(0&, 0&, 0&, 0&)
    Select Case WaitForDesiredType
      Case Is < 0& '-1& 'waitforall
        If AllTears_TypesCount < -WaitForDesiredType Then Exit Do
        'If AllTears_TypesCount < 2& Then Exit Do
         ' 1 left for last one still opened
      Case 0& ' -1 reserved  any = stream/tracker
        If AllTears_TypesCount = ctSSLayer_MaxIDs Then
          ShortenWeakTear
          Else
          Exit Do
          End If
      Case 1& To MaxWaitID ' wait for midis / cdda
        If AllTears_Types(WaitForDesiredType) = 0& And Not AllTears_TypesCount = ctSSLayer_MaxIDs Then Exit Do
      End Select
    
    'If Not (xLoadingStream = 0& Or xHiddenAutoDoing) Then
    If Not (xLoadingStream = 0&) Then
      If DoEventsEx_IsTickCountElapsed(xLong1, DoEventsEx_SleepPeriodical_Interval) Then
        Call DoAnimateReadDir(1&)
        xLong1 = (GetTickCount And &H3FFFFFFF)
        End If
      End If
    DoEventsEx_Sleep 25&
    Loop
  End Sub

Private Sub ShortenWeakTear()
  Dim xLong1 As Long
  Dim xLong2 As Long
  Dim xVal1 As Single
  Dim xVal2 As Single

  xLong1 = -1&
  For xLong2 = 0& To ctSSLayer_MaxIDsX
    If Tear_ShouldVolume(xLong2) = 0& And Not (xLong2 = CurrentSongID Or Tear_StepT(xLong2) = 0&) Then
    'If Not (Tear_StepT(xLong2) = 0&) Then
      xVal1 = (Tear_StepT(xLong2) + KeepMusicAliveTime - DoEventsEx_GetElapsedTime(Tear_STime(xLong2)) - Tear_Delay(xLong2)) * Tear_Volume(xLong2)
      If xVal1 < xVal2 Or xLong1 = -1& Then
        xVal2 = xVal1
        xLong1 = xLong2
        End If
      'Debug.Print "Tear", xLong2, xVal1, "MS/Left:", Tear_StepT(xLong2) + KeepMusicAliveTime, (Tear_StepT(xLong2) + KeepMusicAliveTime - DoEventsEx_GetElapsedTime(Tear_STime(xLong2)) - Tear_Delay(xLong2)), "Vol", Tear_Volume(xLong2)
      End If
    Next
  'If xLong1 = CurrentSongID Then
  '  'Debug.Print "I would drop (c) tear ", xLong1, "due", xVal2
  '  Else
  '  'Debug.Print "I would drop     tear ", xLong1, "due", xVal2
  '  End If
  
  If Not xLong1 = -1& And xVal2 < 750& Then
    'Debug.Print "Dropping tear " + CStr(xLong1) + " with value " + CStr(xVal2)
    'If xLong1 = CurrentSongID Then Stop
    'If xLong1 = NewSongID Then Stop
    'If xLong1 = OldSongID Then Stop
    Call Tear_Dropped(xLong1)
    Call ctSSLayer_UnloadSong(SongPointer(xLong1))
    End If
  'SongPointer(xLong2) = 0&
  
  
  End Sub

Public Sub Tear_Dropped(ByRef SongID As Long)
  Tear_StepT(SongID) = 0&
  AllTears_Types(Tear_Type(SongID)) = AllTears_Types(Tear_Type(SongID)) - 1&
  AllTears_TypesCount = AllTears_TypesCount - 1&
  AllTears_IDs = Left(AllTears_IDs, SongID) & vbNullChar & Mid(AllTears_IDs, SongID + 2&)
  If AllTears_TypesCount = 2& Then
    MainForm_TearIconChance
    ElseIf AllTears_TypesCount = AnimateForTearCountX And Not (xPStateIconStartup Or xAutoDoing) Then
    DoAnimateReadDir 0&
    End If
  End Sub

Public Function Tear_Create() As Long
  'Dim xLong1 As Long
  
  Call Tear_WaitFor(0&)
  AllTears_TypesCount = AllTears_TypesCount + 1&
  Tear_Create = InStr(AllTears_IDs, vbNullChar) - 1&
  'If Tear_Create = -1& Then Stop
  AllTears_IDs = Left(AllTears_IDs, Tear_Create) & Chr(1) & Mid(AllTears_IDs, Tear_Create + 2&)
  If AllTears_TypesCount > 2& Then
    MainForm_TearIconChance
    End If
  End Function

Public Sub Tear_StartDropping(ByRef SongID As Long, ByRef DesiredType As Long, ByVal SpecialMode As Long, ByRef Delay As Long, ByRef FullTime As Long, ByRef DesiredVolumeDir As Long)
  If Not SongID = -1& Then
    If SpecialMode = 1& Or SpecialMode = 11& Then
      AllTears_Types(DesiredType) = AllTears_Types(DesiredType) + 1&
      Tear_Type(SongID) = DesiredType
      End If
    Tear_STime(SongID) = DoEventsEx_GetTickCount
    On Error Resume Next ' Specific fmod crash hack...
    Tear_WasVolume(SongID) = Timer
    On Error GoTo 0
    Tear_WasVolume(SongID) = Tear_Volume(SongID)
    Tear_Special(SongID) = SpecialMode
    Tear_Delay(SongID) = Delay ' xfade only, overwrite on action!
    If SpecialMode = 11& Then
      Tear_StepT(SongID) = Delay + FullTime
      Else
      Tear_StepT(SongID) = Delay + FullTime * Abs(DesiredVolumeDir - Tear_WasVolume(SongID)) '* 5
      End If
    
    If Tear_StepT(SongID) = 0& Then Tear_StepT(SongID) = 1&
    Tear_ShouldVolume(SongID) = DesiredVolumeDir
    End If
  
  If SpecialMode < 10& Then 'Or SongID = -1& Then
    For SpecialMode = 0& To ctSSLayer_MaxIDsX
      If Tear_Special(SpecialMode) = 11& And Not Tear_StepT(SpecialMode) = 0& Then
        If Tear_Delay(SpecialMode) + Tear_STime(SpecialMode) - DoEventsEx_GetElapsedTime(Tear_STime(SpecialMode)) > FullTime + Delay Then
          Tear_STime(SpecialMode) = DoEventsEx_GetTickCount
          Tear_WasVolume(SpecialMode) = Tear_Volume(SpecialMode)
          Tear_Delay(SpecialMode) = 0& 'Delay 'Tear_Special(SpecialMode) - 10&
          Tear_Special(SpecialMode) = 1&
          Tear_StepT(SpecialMode) = Delay + FullTime '* Abs(Tear_ShouldVolume(SpecialMode) - Tear_WasVolume(SpecialMode)) 'FullTime
          If Tear_StepT(SpecialMode) = 0& Then Tear_StepT(SpecialMode) = 1&
          End If
        End If
      Next
    End If
  End Sub

Public Sub TearDown(ByVal ptrStream As Long, ByVal xBuff As Long, ByVal xLen As Long, ByVal xParam As Long)
  Dim xLong2 As Long
  Dim xLong3 As Long
  Dim xSingle1 As Single
  Static xBool1 As Boolean
  Dim xType1 As POINTAPI
  Static xType2 As POINTAPI
  Static HasMovedState As Boolean
  Static AnimateReadDirTM As Long

  #If NewKeyMode Then
    Static xLong4 As Long
    'Static xLong5 As Long
    #End If
  
    For xLong2 = 0& To ctSSLayer_MaxIDsX
      If Not Tear_StepT(xLong2) = 0& Then
        xLong3 = DoEventsEx_GetElapsedTime(Tear_STime(xLong2)) - Tear_Delay(xLong2)
        If xLong3 > 0& Then
          If xLong3 > Tear_StepT(xLong2) Then
            If Not Tear_Volume(xLong2) = Tear_ShouldVolume(xLong2) Then
              Call ctSSLayer_SetVolume(SongPointer(xLong2), xSetVolume * Tear_ShouldVolume(xLong2))
              Tear_Volume(xLong2) = Tear_ShouldVolume(xLong2)
              End If
            If xLong3 > Tear_StepT(xLong2) + KeepMusicAliveTime Then
              Tear_StepT(xLong2) = 0&
              Select Case Tear_Special(xLong2)
                Case 1&, 11&
                  Call Tear_Dropped(xLong2)
                  Call ctSSLayer_UnloadSong(SongPointer(xLong2))
                  'SongPointer(xLong2) = 0&
                Case 2&
                  Call ctSSLayer_SetPause(SongPointer(xLong2), True)
                Case 3&
                  MainForm_RestartEx
                End Select
              End If
            Else
            xSingle1 = (1 - Cos((Tear_WasVolume(xLong2) + (Tear_ShouldVolume(xLong2) - Tear_WasVolume(xLong2)) * xLong3 / Tear_StepT(xLong2)) * 3.14159265)) / 2
            Call ctSSLayer_SetVolume(SongPointer(xLong2), CInt(xSingle1 * xSetVolume))
            Tear_Volume(xLong2) = xSingle1
            End If
          End If
        End If
      Next
    
  If Not xBool1 Then
    xBool1 = True
    
    If IsDialoging = 0& And OutOfSessionPause And NotOutOfSessionOld Then
      #If NewKeyMode Then
        If GlobalKeys Then
          xLong4 = 0&
          'xLong5 = 0&
          If (GetAsyncKeyState(&H10&) And &HFFFF0000) Then
            'Shift
            xLong3 = &H100&
            Else
            xLong3 = 0&
            End If
          
          If GetAsyncKeyState(&H12&) And &HFFFF0000 Then
            'alt
            If GetAsyncKeyState(&H11&) And &HFFFF0000 Then
              'ctrl
              'Debug.Print "RespondTo2: ", xLong3
              For xLong2 = 0& To KbdCountX_Minus_KbdSplitN
                If xKeyReg(xLong2) And (xKey(xLong2 + KbdSplitN) And &H100&) = xLong3 Then
                  'Debug.Print "RespondTo3: ", Hex(xKey(xLong2 + KbdSplitN))
                  If Not UnassignedKey(xKey(xLong2 + KbdSplitN)) Then
                    If GetAsyncKeyState(xKey(xLong2 + KbdSplitN) And &HFF&) And &HFFFF0000 Then
  #If ShowRegKeyStuff Then
                      MainForm_ctConsoleA_AddLog "GlobalKey: " + Hex(xKey(xLong2 + KbdSplitN))
  #End If
                      xLong4 = xLong2 + KbdSplitN
                      End If
                    End If
  #If ShowRegKeyStuff Then
                  Else
                  If xKeyReg(xLong2) Then
                  '  Debug.Print "NoRespondTo3: ", Hex(xKey(xLong2 + KbdSplitN))
                    ElseIf Not xKey(xLong2 + KbdSplitN) = 0& Then
'                    MainForm_ctConsoleA_AddLog "Unset3: " + Hex(xKey(xLong2 + KbdSplitN))
                    End If
  #End If
                  End If
                Next
              End If
            Else
            'If GetAsyncKeyState(&H11&) And &HFFFF0000 Then
            '  'ctrl
            '  xLong3 = xLong3 Or &H200&
            '  End If
            For xLong2 = 0& To KbdCountX_Minus_KbdSplitN
              If xKeyReg(xLong2) And (xKey(xLong2 + KbdSplitN) And &H100&) = xLong3 Then
                If UnassignedKey(xKey(xLong2 + KbdSplitN)) Then
                  If GetAsyncKeyState(xKey(xLong2 + KbdSplitN) And &HFF&) And &HFFFF0000 Then
  #If ShowRegKeyStuff Then
                      MainForm_ctConsoleA_AddLog "SpecialKey: " + Hex(xKey(xLong2 + KbdSplitN))
  #End If
                    xLong4 = xLong2 + KbdSplitN
                    End If
                  
                  Else
                  
                  End If
  #If ShowRegKeyStuff Then
                Else
                If xKeyReg(xLong2) = 0& Then
                '  Debug.Print "NoRespondTo3: ", Hex(xKey(xLong2 + KbdSplitN))
                  If Not xKey(xLong2 + KbdSplitN) = 0& Then
'                    MainForm_ctConsoleA_AddLog "Unset6: " + Hex(xKey(xLong2 + KbdSplitN))
                    End If
                  End If
  #End If
                End If
              Next
            End If
          
          'Debug.Print "HK: ", xLong4, RGK_xOldKey
          If xLong4 = RGK_xOldKey Then
            If Not xLong4 = 0& Then
'Debug.Print "HotKeyEx again"
              If DoEventsEx_IsTickCountElapsed(RGK_xOldKeyTime, RGK_xOldKeyTimeWait) Then
                Select Case xLong4
                  Case KbdC_GShowMenu, KbdC_GShowAltMenu, KbdC_GShowVolMenu, KbdC_GShowTitle
'Debug.Print "NoRepeat"
                  Case Else
#If ShowRegKeyStuff Then
  MainForm_ctConsoleA_AddLog "KeyEvent: " + Hex(xLong4)
  #End If
                    MainForm_ProcessKey xLong4
                  End Select
                RGK_xOldKeyTime = DoEventsEx_GetTickCount
                RGK_xOldKeyTimeWait = RGK_xOldKeyTimeWaitShort
                If xLong4 = KbdC_GShowTitle Then 'KbdC_GShowTitle_Fast Then
                  ShowIRTicks = RGK_xOldKeyTime
                  End If
                End If
              'Else
              'Debug.Print "HotKeyNot again"
              End If
            Else
            If Not xLong4 = 0& Then
'Debug.Print "HotKeyEx first", xLong4, RGK_xOldKey
              MainForm_ProcessKey xLong4
              RGK_xOldKeyTime = DoEventsEx_GetTickCount
              RGK_xOldKeyTimeWait = RGK_xOldKeyTimeWaitLong
'Else
'Debug.Print "HotKeyNot removed"
              End If
            If RGK_xOldKey = KbdC_GShowTitle And RGK_xOldKeyTimeWait = RGK_xOldKeyTimeWaitShort Then
              MainForm_HideIRWin
              End If
            RGK_xOldKey = xLong4
'Debug.Print "LP: ", RGK_xOldKey
            End If
          End If
        #End If
      If AllTears_TypesCount > AnimateForTearCountX Or xForceAnimationNow Or xPStateIconSndcard Then
        AnimateReadDirTM = 1& - AnimateReadDirTM
        If AnimateReadDirTM = 0& And (xPStateIconSndcard Or xForceAnimationNow Or Not (xPStateIconStartup Or xAutoDoing Or xLoadingStream)) Then
          DoAnimateReadDir 1&
          End If
        End If
      End If




    Call GetCursorPos(xType1)
    If GetForegroundWindow = MainHWnd Then
      If HasMovedState Then
RePossible:
        If Not (PlayerInMenuLoop Or MainFormIsSplitterMoving) Then
          ptrStream = -1&
          
          'If xType1.x = xType2.x And xType1.y = xType2.y Then
            xLong2 = WindowFromPoint(xType1.x, xType1.y)
            'Debug.Print "CheckWin", xLong2, xStaticIconsHWnd(9&)
            For xLong3 = 0& To xStaticIcons_Tags
              If xStaticIconsHWnd(xLong3) = xLong2 Then
                ptrStream = xLong3
                'Debug.Print "FoundWindow", xLong3, xLong2, xStaticIconsHWnd(9&)
                Exit For
                End If
              Next
            'Debug.Print
            If ptrStream = CurShownToolTip Then
              If Not CurShownToolTip = -1& Then
                If ToolTipInitTime = -1& Then
                  If Not (xType1.x = xType2.x And xType1.y = xType2.y) Then
                    If ToolTipDelay = 0& Then
#If ShowMoreTTInfo Then
Debug.Print "ReCalcPos"
#End If
                      CalcToolTip
                      Else
#If ShowMoreTTInfo Then
'Debug.Print "HideForAnotherPos"
Debug.Print "IgnoreStillInControl"
#End If
'                      GoTo ReSetTT
    '                  GoTo HideOld
                      End If
                    End If
                  Else
                  If (xType1.x = xType2.x And xType1.y = xType2.y) Then
                    If DoEventsEx_IsTickCountElapsed(ToolTipInitTime, ToolTipDelay) Then
#If ShowMoreTTInfo Then
Debug.Print "FirstShow"
#End If
ShowNow:
                      ToolTipInitTime = -1&
                      CalcToolTip
                      ShowWindow xStaticIconsHWnd(xStaticIcons_ToolTip), 4&
                      End If
                    Else
                    GoTo ReSetTTime
                    End If
                  End If
                End If
              Else
              CurShownToolTip = ptrStream
              If CurShownToolTip = -1& Then
#If ShowMoreTTInfo Then
Debug.Print "HideAnyOldOnly"
#End If
HideOld:
                If ToolTipInitTime = -1& Then ShowWindow xStaticIconsHWnd(xStaticIcons_ToolTip), 0&
                Else
                If ToolTipDelay = 0& Then
#If ShowMoreTTInfo Then
Debug.Print "ShowImmediatelly"
#End If
                  ShowWindow xStaticIconsHWnd(xStaticIcons_ToolTip), 0&
                  GoTo ShowNow
                  Else
#If ShowMoreTTInfo Then
Debug.Print "SetAndWait"
#End If
ReSetTT:
                  If ToolTipInitTime = -1& Then ShowWindow xStaticIconsHWnd(xStaticIcons_ToolTip), 0&
ReSetTTime:
                  ToolTipInitTime = DoEventsEx_GetTickCount
                  'GoTo HideOld
                  End If
                'Debug.Print "ToolTip!", CurShownToolTip, ptrStream
                End If
              End If
            'xType2.x = xType1.x
            'xType2.y = xType1.y
            
            'Else
            'xType2.x = xType1.x
            'xType2.y = xType1.y
            'End If
          
          ElseIf Not CurShownToolTip = -1& Then
HideAll:
#If ShowMoreTTInfo Then
Debug.Print "OutPossible"
#End If
          CurShownToolTip = -1&
          GoTo HideOld
          'If ToolTipInitTime = -1& Then ShowWindow xStaticIconsHWnd(xStaticIcons_ToolTip), 0&
          End If
        ElseIf Not (xType1.x = xType2.x And xType1.y = xType2.y) Then
#If ShowMoreTTInfo Then
Debug.Print "IsPossible"
#End If
        HasMovedState = True
        GoTo RePossible
        End If
      ElseIf HasMovedState Then
      HasMovedState = False
#If ShowMoreTTInfo Then
Debug.Print "OutStanding"
#End If
      GoTo HideAll
      End If
    xType2.x = xType1.x
    xType2.y = xType1.y
    xBool1 = False
    End If
  End Sub

Public Sub ReSetTearArrayCount()
  ctSSLayer_MaxIDs = ctSSLayer_CanUseItem(&HD&) + 1&
  'ctSSLayer_MaxIDs = 3&
  If ctSSLayer_MaxIDs < 2& Then ctSSLayer_MaxIDs = 2&
  
  
  'ctSSLayer_MaxIDs = 5&
  
  If ctSSLayer_MaxIDs > 16& Then ctSSLayer_MaxIDs = 16& 'enough for music!
  ctSSLayer_MaxIDsX = ctSSLayer_MaxIDs - 1&
  
  AllTears_IDs = String(ctSSLayer_MaxIDs, vbNullChar)
  
  ReDim Tear_Type(ctSSLayer_MaxIDsX)
  ReDim Tear_STime(ctSSLayer_MaxIDsX)
  ReDim Tear_Delay(ctSSLayer_MaxIDsX)
  ReDim Tear_WasVolume(ctSSLayer_MaxIDsX)
  ReDim Tear_Volume(ctSSLayer_MaxIDsX)
  ReDim Tear_Special(ctSSLayer_MaxIDsX)
  ReDim Tear_ShouldVolume(ctSSLayer_MaxIDsX)
  ReDim Tear_StepT(ctSSLayer_MaxIDsX)
  ReDim SongPointer(ctSSLayer_MaxIDsX)
  
  AnimateForTearCountX = ctSSLayer_MaxIDsX '- 1&
  End Sub

Public Sub TearDown_Relocate(ByVal OrgTimer As Long)
  Dim xLong1 As Long
  
  OrgTimer = DoEventsEx_GetElapsedTime(OrgTimer)
  For xLong1 = 0& To ctSSLayer_MaxIDsX
    If Not Tear_StepT(xLong1) = 0& Then
      Tear_STime(xLong1) = ((Tear_STime(xLong1) + OrgTimer) And &H3FFFFFFF)
      End If
    Next
  End Sub

