﻿Attribute VB_Name = "SquareClickSession"
Option Explicit

' SquareClick Standard 1.2: save-safe runtime UI for ordinary .xlsx books.
' BEFORE saving, all SquareClick click-target shapes are deleted and all
' native form checkboxes restored. AFTER saving, runtime click UI is rebuilt.
' Only works when Excel application events are enabled.
' No save command is replaced and no network, Shell, or file I/O is used.

Private mBusy As Boolean
Private mPending As Excel.Workbook

Public Function SCSession_IsBusy() As Boolean
    SCSession_IsBusy = mBusy
End Function

' Avoid rebuilding overlays between BeforeSave and the actual SaveAs dialog.
Public Function SCSession_IsSaving(ByVal wb As Excel.Workbook) As Boolean
    If wb Is Nothing Then Exit Function
    SCSession_IsSaving = SCSession_SameWorkbook(mPending, wb)
End Function

Private Function SCSession_SameWorkbook(ByVal x As Excel.Workbook, _
                                         ByVal y As Excel.Workbook) As Boolean
    If x Is Nothing Or y Is Nothing Then Exit Function
    SCSession_SameWorkbook = (x Is y)
End Function

Public Sub SCSession_BeforeSave(ByVal wb As Excel.Workbook, _
                                 ByRef Cancel As Boolean)
    Dim ws As Excel.Worksheet
    Dim msg As String

    If mBusy Then Exit Sub
    If wb Is Nothing Then Exit Sub
    If wb Is ThisWorkbook Then Exit Sub
    If Cancel Then Exit Sub

    mBusy = True
    On Error GoTo CleanFail
    For Each ws In wb.Worksheets
        ' Remove our form-control overlays first; restore native checkboxes.
        If Not SquareClickStandard.SCStd_CleanSheet(ws) Then
            msg = "Checkbox overlays could not be cleared on: " & ws.name
            GoTo CleanFail
        End If
        If Not SquareClickCore.SquareClick_CleanSheet(ws) Then
            msg = "List click targets could not be cleared on: " & ws.name
            GoTo CleanFail
        End If
    Next ws

    Set mPending = wb
    mBusy = False
    Exit Sub

CleanFail:
    ' Fail closed: do not silently save any path-bearing macros into the book.
    Cancel = True
    mBusy = False
    If Len(msg) = 0 Then msg = Err.Description
    MsgBox "SquareClick stopped this save because its temporary click targets" & _
           " could not be removed." & vbCrLf & msg & vbCrLf & _
           "Try SCSession_RefreshActive after checking sheet protection.", _
           vbExclamation, "SquareClick Standard 1.2"
    On Error Resume Next
    SCSession_RestoreRuntime wb, False
End Sub

Public Sub SCSession_AfterSave(ByVal wb As Excel.Workbook, _
                                ByVal Success As Boolean)
    If wb Is Nothing Then Exit Sub
    If wb Is ThisWorkbook Then Exit Sub
    If Not SCSession_SameWorkbook(mPending, wb) Then Exit Sub
    Set mPending = Nothing

    SCSession_RestoreRuntime wb, Success
End Sub

Private Sub SCSession_RestoreRuntime(ByVal wb As Excel.Workbook, _
                                      ByVal savedOK As Boolean)
    Dim act As Object
    If mBusy Then Exit Sub
    If wb Is Nothing Then Exit Sub
    On Error GoTo Done

    mBusy = True
    Set act = wb.ActiveSheet
    If Not act Is Nothing Then
        If TypeOf act Is Excel.Worksheet Then
            SquareClickStandard.SCStd_ApplySheet act
            If SquareClickStandard.SCStd_AllowListForWorkbook(wb) Then
                SquareClickCore.SquareClick_PrepareSheet act
            End If
        End If
    End If

    ' UI-only overlays were re-created AFTER the file was written. They change
    ' the in-memory drawing layer but not the saved data; avoid a false prompt.
    If savedOK Then wb.Saved = True
Done:
    mBusy = False
End Sub

' Recovery if the Save As dialog was cancelled (AfterSave may not be raised).
' Called only on the next worksheet/user activity, never during save UI.
Public Sub SCSession_OnUserActivity(ByVal wb As Excel.Workbook)
    If mBusy Then Exit Sub
    If wb Is Nothing Then Exit Sub
    If wb Is ThisWorkbook Then Exit Sub
    If SCSession_SameWorkbook(mPending, wb) Then
        Set mPending = Nothing
        SCSession_RestoreRuntime wb, False
    End If
End Sub

' Manual repair, e.g. cancelled Save As that leaves native controls visible.
Public Sub SCSession_RefreshActive()
    Dim wb As Excel.Workbook
    On Error GoTo Fail
    Set wb = Application.ActiveWorkbook
    If wb Is Nothing Then Exit Sub
    If wb Is ThisWorkbook Then Exit Sub
    Set mPending = Nothing
    SCSession_RestoreRuntime wb, False
    Exit Sub
Fail:
    MsgBox "SquareClick refresh error: " & Err.Description, vbExclamation
End Sub

' Read-only: checks whether Excel still reports external workbook links.
' An old book might already contain a link left by version 1.1.
Public Sub SCSession_AuditActiveLinks()
    Dim wb As Excel.Workbook
    Dim v As Variant
    Dim i As Long, result As String
    On Error GoTo Fail
    Set wb = Application.ActiveWorkbook
    If wb Is Nothing Then Exit Sub
    v = wb.LinkSources(xlExcelLinks)
    If IsEmpty(v) Then
        MsgBox "Excel reports no external Excel workbook links.", _
               vbInformation, "SquareClick link audit"
        Exit Sub
    End If
    For i = LBound(v) To UBound(v)
        If Len(result) < 1600 Then
            result = result & CStr(v(i)) & vbCrLf
        End If
    Next i
    MsgBox "External Excel workbook links found:" & vbCrLf & result & _
           vbCrLf & "No links were changed.", vbExclamation, _
           "SquareClick link audit"
    Exit Sub
Fail:
    MsgBox "Could not inspect workbook links: " & Err.Description, vbExclamation
End Sub
