Attribute VB_Name = "modGlobal"
' Copyright (C) 2007 Stephane Germain <stephane.germain@gmail.com>
'
' 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA

Option Explicit
Option Base 0

' constants
Public Const ProgName = "eirt"
Public Const NbrStep = 4
Public Const NbrLang = 2
Public Const TrueCode = 1
Public Const FalseCode = 0
Public Const BlankCode = -1
Public Const NominalModelCode = 4
Public Const GradedModelCode = 5

' global variables
Public StepNum As Integer 'the current step
Public WirtSerial As Integer ' to give a unique name to the report sheet
' collected in the select form
Public NbrSubject As Long
Public NbrItem As Long
Public RawData As Range
Public SubjectLabels() As String
Public ItemLabels() As String
Public Key() As String
Public HaveKey As Boolean ' if the key is in the selection
' collected in the data form
Public Binary As Boolean
Public MC As Boolean
Public Graded As Boolean
Public Mixed As Boolean
Public SuccessString As String
Public MissingString As String
' collected in the model form
Public PLM1 As Boolean
Public PLM2 As Boolean
Public PLM3 As Boolean
Public NominalModel As Boolean
Public GradedModel As Boolean
Public Kernel As Boolean
Public Penalized As Boolean
Public Models() As Long
Public DataTypes() As Long
' collected in the report form
Public CTT As Boolean
Public Fit As Boolean
Public LD As Boolean
Public Parameter As Boolean
Public Ability As Boolean
Public Curves As Boolean
Public Information As Boolean
Public SE As Boolean
Public DataPoints As Boolean
Public PairsCorr As Boolean
Public Score As Boolean
Public ScoreAbscisse As Boolean
Public ShowIntercept As Boolean

' Settings
Public Version As String
Public LangCode As Integer
Public AbilName As String
Public NbrQuad As Long
Public QuadFrom As Double
Public QuadTo As Double
Public PenalizedFactor As Double
Public KernelFactor As Double
Public SlopePrior As Long
Public ThreshPrior As Long
Public AsympPrior As Long
Public SlopeMean As Double
Public SlopeDev As Double
Public ThreshMean As Double
Public ThreshDev As Double
Public AsympMean As Double
Public AsympWeight As Double
Public MaxEMiter As Long
Public MaxNRiter As Long
Public Precision As Double
Public Grouping As Long
Public AbilEstim As String
Public FixedSlope As Double
Public NormalOgive As Long
Public PolyserialCorr As Long
   
    
Public Function Exists(col As Collection, ByVal Key As String) As Boolean
On Error Resume Next
Exists = False
Exists = Not col(Key) Is Nothing
On Error GoTo NotExists
Dim item As Variant
item = col(Key)
Exists = True
NotExists:
End Function

Public Sub ReadSetting()
    ' we read with a point as decimal
    Version = GetSetting(ProgName, "Config", "Version", "0.0.0")
    LangCode = Int(Val(GetSetting(ProgName, "Config", "LangCode", "1")))
    AbilName = GetSetting(ProgName, "Config", "AbilName", "Z")
    NbrQuad = Int(Val(GetSetting(ProgName, "Config", "NbrQuad", "64")))
    QuadFrom = Val(GetSetting(ProgName, "Config", "QuadFrom", "-4"))
    QuadTo = Val(GetSetting(ProgName, "Config", "QuadTo", "4"))
    PenalizedFactor = Val(GetSetting(ProgName, "Config", "PenalizedFactor", "4"))
    KernelFactor = Val(GetSetting(ProgName, "Config", "KernelFactor", "2.7"))
    SlopePrior = Int(Val(GetSetting(ProgName, "Config", "SlopePrior", "1")))
    ThreshPrior = Int(Val(GetSetting(ProgName, "Config", "ThreshPrior", "0")))
    AsympPrior = Int(Val(GetSetting(ProgName, "Config", "AsympPrior", "1")))
    SlopeMean = Val(GetSetting(ProgName, "Config", "SlopeMean", "1.702"))
    SlopeDev = Val(GetSetting(ProgName, "Config", "SlopeDev", "2.8"))
    ThreshMean = Val(GetSetting(ProgName, "Config", "ThreshMean", "0"))
    ThreshDev = Val(GetSetting(ProgName, "Config", "ThreshDev", "2"))
    AsympMean = Val(GetSetting(ProgName, "Config", "AsympMean", "0.2"))
    AsympWeight = Val(GetSetting(ProgName, "Config", "AsympWeight", "20"))
    MaxEMiter = Int(Val(GetSetting(ProgName, "Config", "MaxEMiter", "100")))
    MaxNRiter = Int(Val(GetSetting(ProgName, "Config", "MaxNRiter", "100")))
    Precision = Val(GetSetting(ProgName, "Config", "Precision", "1e-5"))
    Grouping = Int(Val(GetSetting(ProgName, "Config", "Grouping", "1")))
    AbilEstim = GetSetting(ProgName, "Config", "AbilEstim", "EAP")
    NormalOgive = Int(Val(GetSetting(ProgName, "Config", "NormalOgive", "0")))
    PolyserialCorr = Int(Val(GetSetting(ProgName, "Config", "PolyserialCorr", "0")))
    FixedSlope = Val(GetSetting(ProgName, "Config", "FixedSlope", "1.0"))
End Sub

Public Sub WriteSetting()
    ' we save with a point for the decimal
    Call SaveSetting(ProgName, "Config", "Version", Version)
    Call SaveSetting(ProgName, "Config", "LangCode", Str(LangCode))
    Call SaveSetting(ProgName, "Config", "AbilName", AbilName)
    Call SaveSetting(ProgName, "Config", "NbrQuad", Str(NbrQuad))
    Call SaveSetting(ProgName, "Config", "QuadFrom", Str(QuadFrom))
    Call SaveSetting(ProgName, "Config", "QuadTo", Str(QuadTo))
    Call SaveSetting(ProgName, "Config", "PenalizedFactor", Str(PenalizedFactor))
    Call SaveSetting(ProgName, "Config", "KernelFactor", Str(KernelFactor))
    Call SaveSetting(ProgName, "Config", "SlopePrior", Str(SlopePrior))
    Call SaveSetting(ProgName, "Config", "ThreshPrior", Str(ThreshPrior))
    Call SaveSetting(ProgName, "Config", "AsympPrior", Str(AsympPrior))
    Call SaveSetting(ProgName, "Config", "SlopeMean", Str(SlopeMean))
    Call SaveSetting(ProgName, "Config", "SlopeDev", Str(SlopeDev))
    Call SaveSetting(ProgName, "Config", "ThreshMean", Str(ThreshMean))
    Call SaveSetting(ProgName, "Config", "ThreshDev", Str(ThreshDev))
    Call SaveSetting(ProgName, "Config", "AsympMean", Str(AsympMean))
    Call SaveSetting(ProgName, "Config", "AsympWeight", Str(AsympWeight))
    Call SaveSetting(ProgName, "Config", "MaxEMiter", Str(MaxEMiter))
    Call SaveSetting(ProgName, "Config", "MaxNRiter", Str(MaxNRiter))
    Call SaveSetting(ProgName, "Config", "Precision", Str(Precision))
    Call SaveSetting(ProgName, "Config", "Grouping", Str(Grouping))
    Call SaveSetting(ProgName, "Config", "AbilEstim", AbilEstim)
    Call SaveSetting(ProgName, "Config", "NormalOgive", Str(NormalOgive))
    Call SaveSetting(ProgName, "Config", "PolyserialCorr", Str(PolyserialCorr))
    Call SaveSetting(ProgName, "Config", "FixedSlope", Str(FixedSlope))
End Sub

' The localized strings are in a sheet in this workbook.
' To see this sheet, change the "IsAddin" propertie of this workbook to False.
Public Function GText(s As String, Optional opt1 As Variant, _
        Optional opt2 As Variant, Optional opt3 As Variant) As String
    On Error GoTo errorEnd
    GText = ThisWorkbook.Worksheets("gettext").Range(s).Cells(1, LangCode)
    If Not IsMissing(opt1) Then GText = Replace(GText, "%1", opt1)
    If Not IsMissing(opt2) Then GText = Replace(GText, "%2", opt2)
    If Not IsMissing(opt3) Then GText = Replace(GText, "%3", opt3)
    Exit Function
errorEnd:
    GText = "?"
End Function

Public Sub AboutWirt()
    MsgBox ProgName & " version " & Version & " (https://psychometricon.net/libirt/)", _
        vbInformation, ProgName
End Sub

Public Sub WirtHelp()
    'Application.Help ThisWorkbook.Path & "\index.html"
    'Shell "explorer " & ThisWorkbook.Path & "\..\doc\" & ProgName & "-" & GText("LangAbbrev") & "\index.html", vbMaximizedFocus
    Call ShellExecute(0, "open", _
        ThisWorkbook.Path & "\..\doc\" & ProgName & "-" & GText("LangAbbrev") & "\index.html", _
        "", "", 1)
End Sub

Public Sub StartWirt()
    StepNum = 1
    frmSelect.resetSelection = True
    frmSelect.Show
End Sub

Public Sub WirtSettings()
    frmSettings.Show
End Sub

Public Function OrderOptions(ByVal OptionsNames As Collection, ByRef OptionsCol As Collection) As Collection
    Dim i As Integer, j As Integer, n As Long, imin As Integer
    Dim tmp As String
    Set OrderOptions = New Collection
    n = OptionsNames.Count
    For i = 1 To n
        OrderOptions.Add OptionsNames(i)
    Next i
    For i = 1 To n
        tmp = OrderOptions.item(i)
        imin = i
        If i < n Then
            For j = i + 1 To n
                If tmp > OrderOptions.item(j) Then
                    tmp = OrderOptions.item(j)
                    imin = j
                End If
            Next j
        End If
        If imin <> i Then OrderOptions.Add OrderOptions.item(i), , , imin
        OrderOptions.Add OrderOptions.item(imin), CStr(i), , i
        OrderOptions.Remove i
        If imin <> i Then OrderOptions.Remove imin
    Next i
    Set OptionsCol = New Collection
    For i = 1 To n
        OptionsCol.Add i, OrderOptions.item(i)
    Next i
End Function

