<!--#include file="../app/Controllers/autoload_controllers.asp" -->
<%
' Every response is dynamic and session-sensitive (CSRF tokens, flash messages), so tell
' every cache - browser, proxy, or antivirus web filter - not to store it at all.
'
' Response.CacheControl is ASP's intrinsic property that actually governs the real
' Cache-Control header IIS sends, and it defaults to "private" (which explicitly PERMITS
' browser-local caching) if never set. Response.AddHeader "cache-control", ... does NOT
' touch that property - it adds a second, separate Cache-Control header alongside it, which
' a real proxy/cache can parse unpredictably (confirmed via debug logging: a response still
' reported Response.CacheControl = "private" even after AddHeader was called). Must set the
' CacheControl property directly for this to actually take effect.
Response.ExpiresAbsolute = Now() - 1
Response.CacheControl = "no-cache"
Response.AddHeader "pragma", "no-cache"
'=======================================================================================================================
' MVC Dispatcher
'=======================================================================================================================
Class MVC_Dispatcher_Class
    dim CurrentController

    Public Property Get ControllerName
        ControllerName = CurrentController
    end Property

    '---------------------------------------------------------------------------------------------------------------------
    ' Convenience method to resolve route and dispatch in one call
    ' method: HTTP method (GET, POST, etc.)
    ' path: Request path (already cleaned of query params)
    '---------------------------------------------------------------------------------------------------------------------
    Public Sub DispatchRequest(method, path)
        Dim routeArray
        routeArray = router.Resolve(method, path)
        Dispatch routeArray
    End Sub

    '---------------------------------------------------------------------------------------------------------------------
    ' Main dispatch method - executes a resolved route
    ' RouteArray: Array(controller, action, params) from router.Resolve()
    '---------------------------------------------------------------------------------------------------------------------
    Public Sub Dispatch(RouteArray)
        On Error Resume Next
        Dim controllerName, actionName, hasParams, paramsArray
        controllerName = RouteArray(0)
        actionName = RouteArray(1)

        ' Security: Validate controller and action names
        If Not ControllerRegistry.IsValidControllerFormat(controllerName) Then
            Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
            Response.Write "<strong>Security Error:</strong> Invalid controller name format."
            Response.Write "</div>"
            Exit Sub
        End If

        If Not ControllerRegistry.IsValidActionFormat(actionName) Then
            Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
            Response.Write "<strong>Security Error:</strong> Invalid action name format."
            Response.Write "</div>"
            Exit Sub
        End If

        ' Security: Check controller whitelist
        If Not ControllerRegistry.IsValidController(controllerName) Then
            Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
            Response.Write "<strong>Security Error:</strong> Controller '" & Server.HTMLEncode(controllerName) & "' is not registered."
            Response.Write "</div>"
            Exit Sub
        End If

        ' Initialize current controller
        Dim controllerAssignment : controllerAssignment = "Set CurrentController = " & controllerName & "()"
        Execute controllerAssignment

        ' Check if layout should be used
        hasParams = (UBound(RouteArray) >= 2)
        If eval(controllerName & ".useLayout") Then
            %> <!-- #include file="../app/views/Shared/Header.asp" --> <%
        End If

        ' Prepare parameters
        If hasParams Then
            paramsArray = SurroundStringInArray(RouteArray(2))
        Else
            paramsArray = Empty
        End If

        ' Execute controller action
        ExecuteControllerAction controllerName, actionName, paramsArray

        ' Include footer if layout is used
        If eval(controllerName & ".useLayout") Then
            %> <!-- #include file="../app/views/Shared/Footer.asp" --> <%
        End If
        On Error GoTo 0
    End Sub

    ' Helper method to execute controller actions (eliminates code duplication)
    Private Sub ExecuteControllerAction(controllerName, actionName, paramsArray)
        On Error Resume Next
        Dim callString

        ' Build the call string based on whether we have parameters
        If Not IsEmpty(paramsArray) And IsArray(paramsArray) And UBound(paramsArray) >= 0 Then
            callString = "Call " & controllerName & "." & actionName & "(" & Join(paramsArray, ",") & ")"
        Else
            callString = "Call " & controllerName & "." & actionName & "()"
        End If

        ' Execute the action
        Execute callString

        ' Handle errors
        If Err.Number <> 0 Then
            HandleDispatchError actionName, Err.Description, Err.Number
            Err.Clear
        End If
        On Error GoTo 0
    End Sub

    ' Centralized error handling for dispatch errors
    Private Sub HandleDispatchError(actionName, errorDesc, errorNum)
        Dim isDevelopment
        isDevelopment = (LCase(GetAppSetting("Environment")) = "development")

        If isDevelopment Then
            Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
            Response.Write "<strong>Controller Action Error</strong><br>"
            Response.Write "Action: <code>" & Server.HTMLEncode(actionName) & "</code><br>"
            Response.Write "Error: " & Server.HTMLEncode(errorDesc) & "<br>"
            Response.Write "Error Number: " & errorNum
            Response.Write "</div>"
        Else
            Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
            Response.Write "<strong>An error occurred</strong><br>"
            Response.Write "Please contact the system administrator if the problem persists."
            Response.Write "</div>"
        End If
    End Sub
        
    Public Sub RequirePost
    
        If Request.Form.Count = 0 Then MVC.RedirectToExt "NotValid","",empty:End If

    End Sub

    ' Shortcut for RedirectToActionExt that does not require passing a parameters argument.
    Public Sub RedirectToAction(ByVal action_name)
        RedirectToActionExt action_name, empty
    End Sub

       Public Sub RedirectTo(controller_name, action_name)
        RedirectToExt controller_name, action_name, empty
    End Sub
    
    ' Redirects the browser to the specified action on the specified controller with the specified querystring parameters.
    ' params is a KVArray of querystring parameters.
    Public Sub RedirectToExt(controller_name, action_name, params)
        Response.Redirect Routes.UrlTo(controller_name, action_name, params)
    End Sub

    Public Sub RedirectToActionExt(ByVal action_name, ByVal params)
        RedirectToExt ControllerName, action_name, params
    End Sub

End Class
dim MVC_Dispatcher_Class__Singleton
Function MVC()
    if IsEmpty(MVC_Dispatcher_Class__Singleton) then
        set MVC_Dispatcher_Class__Singleton = new MVC_Dispatcher_Class
    end if
    set MVC = MVC_Dispatcher_Class__Singleton
End Function
%>