Attribute VB_Name = "ex_ConceptCore"
'================ CCL wrapper =========================
' Shared module version: 20220713
' Tested in:
' Depends on:
' Required reference:
Option Private Module
Option Explicit

Private Const CONCEPT_DLL_LOCATION = "C:\Tools\dll"

#If Win64 Then
  Private Const CCL_DLL_NAME = "ConceptCore64.dll"
  Private Declare PtrSafe Function ConvertToASCII Lib "ConceptCore64.dll" ( _
    ByRef vResult As Variant, ByRef vText As Variant) As Long
  Private Declare PtrSafe Function ConvertToMath Lib "ConceptCore64.dll" ( _
    ByRef vResult As Variant, ByVal sText As String) As Long
  Private Declare PtrSafe Function ASTasText Lib "ConceptCore64.dll" ( _
    ByRef vResult As Variant, ByVal sText As String) As Long
#Else
  Private Const CCL_DLL_NAME = "ConceptCore32.dll"
  Private Declare PtrSafe Function ConvertToASCII Lib "ConceptCore32.dll" ( _
    ByRef vResult As Variant, ByRef vText As Variant) As Long
  Private Declare PtrSafe Function ConvertToMath Lib "ConceptCore32.dll" ( _
    ByRef vResult As Variant, ByVal sText As String) As Long
  Private Declare PtrSafe Function ASTasText Lib "ConceptCore32.dll" ( _
    ByRef vResult As Variant, ByVal sText As String) As Long
#End If

Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal sLibrary As String) As Long
Private Declare PtrSafe Function FreeLibrary Lib "kernel32" (ByVal nLibraryHandle As Long) As Long
Private Const HRESULT_OK = 0

Private g_IsConceptLoaded As Boolean

Public Function LoadConceptCore()
  If g_IsConceptLoaded Then _
    Exit Function
  g_IsConceptLoaded = True
  
  If LoadLibrary(CCL_DLL_NAME) <> 0 Then _
    Exit Function
    
  If LoadLibrary(CONCEPT_DLL_LOCATION & "\" & CCL_DLL_NAME) <> 0 Then _
    Exit Function
    
  ' TODO: remove fallback after some time
  ' fallback path for earlier versions of distribution
  If LoadLibrary(VBA.Environ("USERPROFILE") & "\.concept\dll\" & CCL_DLL_NAME) = 0 Then _
    Call Err.Raise(1, Description:="Could not load " & CCL_DLL_NAME)
End Function

Public Function UnloadConceptCore()
  If Not g_IsConceptLoaded Then _
    Exit Function
  Dim nHandle&: nHandle = LoadLibrary(CCL_DLL_NAME)
  Call FreeLibrary(nHandle)
End Function

Public Function MathToASCII(sText$) As String
  On Error GoTo HANDLE_ERROR
  
  LoadConceptCore
  
  Dim vText As Variant: vText = sText
  Dim vResult As Variant
  If ConvertToASCII(vResult, vText) <> HRESULT_OK Then _
    MathToASCII = "ERR: "
  MathToASCII = MathToASCII & vResult
  
  On Error GoTo 0
  Exit Function
  
HANDLE_ERROR:
  Debug.Print Err.Description
  MathToASCII = Err.Description
  On Error GoTo 0
End Function

Public Function ASCIItoMath(sText$) As String
  On Error GoTo HANDLE_ERROR
  
  LoadConceptCore
  
  Dim vResult As Variant
  If ConvertToMath(vResult, sText) <> HRESULT_OK Then _
    ASCIItoMath = "ERR: "
  ASCIItoMath = ASCIItoMath & " " & vResult
  
  On Error GoTo 0
  Exit Function
  
HANDLE_ERROR:
  Debug.Print Err.Description
  ASCIItoMath = Err.Description
  On Error GoTo 0
End Function

Public Function ASCIItoAST(sText$) As String
  On Error GoTo HANDLE_ERROR

  LoadConceptCore
  
  Dim vResult As Variant
  If ASTasText(vResult, sText) <> HRESULT_OK Then _
    ASCIItoAST = "ERR: "
  ASCIItoAST = ASCIItoAST & vResult
  
  On Error GoTo 0
  Exit Function
  
HANDLE_ERROR:
  Debug.Print Err.Description
  ASCIItoAST = Err.Description
  On Error GoTo 0
End Function

