Public Draw As Application
Public Const szAppName As String = "CalendarWizard3"
Public Const szConfigKey As String = "Config"
Public Settings As clsSettings
Public Languages As Collection
Public Pages As Collection
Public Formats As Collection
Public cBlack As clsColor, cWhite As clsColor, cLtGray As clsColor
Public SharedFormatName As String
Public EnglishMonth(1 To 12) As String

Public Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
Public Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Public Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hdc As LongPtr) As Long
Public Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr
Public Declare PtrSafe Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Public Declare PtrSafe Function EnableWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal fEnable As Long) As Long
Public Declare PtrSafe Function SetFocus Lib "user32" (ByVal hwnd As LongPtr) As LongPtr

Private Declare PtrSafe Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long
Private Const LOCALE_IMEASURE = &HD    '  0 = metric, 1 = US
Private Const LOCALE_SYSTEM_DEFAULT = &H800
Private Const LOCALE_USER_DEFAULT = &H400

Public Const LOGPIXELSX = 88        '  Logical pixels/inch in X
Public Const LOGPIXELSY = 90        '  Logical pixels/inch in Y
Public Const VK_CONTROL = &H11

Public Sub CreateCalendar()
    Set Draw = Application
    LoadLanguages
    LoadPages
    LoadFormats
    Set Settings = New clsSettings
    If Not CheckDocumentSettings() Then Exit Sub
    Set cBlack = New clsColor
    Set cWhite = New clsColor
    Set cLtGray = New clsColor
    cBlack.SetCMYKColor 0, 0, 0, 100
    cWhite.SetCMYKColor 0, 0, 0, 0
    cLtGray.SetCMYKColor 0, 0, 0, 10
    MainForm.Show vbModal
End Sub

Public Function Min(v1 As Long, v2 As Long) As Long
    If v1 < v2 Then
        Min = v1
    Else
        Min = v2
    End If
End Function

Private Function AdjustSize(v As Long, ReqSize As Long, RealSize As Long) As Long
    AdjustSize = CDbl(v) * CDbl(RealSize) / ReqSize
End Function

Private Function CheckDocumentSettings() As Boolean
    Dim doc As Document
    Dim shp As Shape
    Dim nRet As VBA.VbMsgBoxResult
    Dim dx As Double, dy As Double, px As Double, py As Double
    Dim s As String, n As Long
    Settings.mInRect = False
    Settings.PageOrgX = 0
    Settings.PageOrgY = 0
    If Draw.Documents.Count Then
        Set doc = Draw.ActiveDocument
        doc.SaveSettings
        Settings.mDocAvailable = True
        doc.Unit = cdrTenthMicron
        doc.ActivePage.GetSize dx, dy
        Settings.mDocWidth = dx
        Settings.mDocHeight = dy
        Settings.mInPlace = True
        Set shp = Draw.ActiveShape
        If Not shp Is Nothing Then
            If shp.Type = cdrRectangleShape Then
                nRet = MsgBox("Do you want to place a calendar inside the currently selected rectangle?", vbYesNoCancel + vbQuestion)
                If nRet = vbCancel Then
                    doc.RestoreSettings
                    CheckDocumentSettings = False
                    Exit Function
                End If
                If nRet = vbYes Then
                    shp.GetBoundingBox px, py, dx, dy
                    Settings.PageOrgX = px
                    Settings.PageOrgY = py
                    Settings.mDocWidth = dx
                    Settings.mDocHeight = dy
                    Settings.mInRect = True
                End If
            End If
        End If
        doc.RestoreSettings
        Select Case doc.Rulers.HUnits
            Case cdrYard, cdrMile, cdrInch, cdrFoot
                Settings.Unit = 0
            Case cdrPixel, cdrPoint
                Settings.Unit = 2
            Case cdrMillimeter, cdrMeter, cdrKilometer, cdrCentimeter
                Settings.Unit = 1
        End Select
    Else
        s = Space$(50)
        n = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, s, Len(s))
        s = Left$(s, n)
        n = Val(s)
        Settings.mDocAvailable = False
        If n Then
            ' Letter
            Settings.mDocWidth = FromInches(8.5)
            Settings.mDocHeight = FromInches(11)
            Settings.Unit = 0
        Else
            ' A4
            Settings.mDocWidth = FromMillimeters(210)
            Settings.mDocHeight = FromMillimeters(297)
            Settings.Unit = 1
        End If
        Settings.mInPlace = False
    End If
    Settings.PageWidth = Settings.mDocWidth
    Settings.PageHeight = Settings.mDocHeight
    Settings.MarginBottom = FromMillimeters(10)
    Settings.MarginLeft = FromMillimeters(10)
    Settings.MarginRight = FromMillimeters(10)
    Settings.MarginTop = FromMillimeters(10)
    DoAdjustFonts -1
    CheckDocumentSettings = True
End Function

Public Sub DoAdjustFonts(ByVal LayoutType As Long)
    Const FontRounding As Long = 2
    Dim Layout As New clsLayout, sm As clsSmallCalendar
    Dim m As New clsMonth, bReset As Boolean
    Dim sx As Long, sy As Long, MinLen As Long
    m.Init 1, 2000
    With Settings
        MinLen = Min(.PageWidth - .MarginLeft - .MarginRight, .PageHeight - .MarginBottom - .MarginTop)
        .Spacing = FromPoints(AdjustSize(600, 2100000, MinLen) / 100)
        If LayoutType < 0 Or LayoutType > 19 Then
            LayoutType = 2
            .Format.lgTitleHeight = (.PageHeight - .MarginBottom - .MarginTop) * 0.2 ' 20% of page size
        End If
        Layout.SetLayout LayoutType, m
        With .Format
            If Not Layout.LargeCalendar Is Nothing Then
                .lgBodyFont.Size = AdjustSize(18 * FontRounding, 1700000, Layout.LargeCalendar.rcHeadAndBody.GetHeight()) / FontRounding
                .lgBodyHighFont.Size = .lgBodyFont.Size
                .lgBodyHolidayFont.Size = AdjustSize(10 * FontRounding, 1700000, Layout.LargeCalendar.rcHeadAndBody.GetHeight()) / FontRounding
                .lgHeadFont.Size = AdjustSize(12 * FontRounding, 1700000, Layout.LargeCalendar.rcHeadAndBody.GetHeight()) / FontRounding
                .lgHeadHighFont.Size = .lgHeadFont.Size
                .lgTitleFont.Size = AdjustSize(40 * FontRounding, 400000, Layout.LargeCalendar.rcTitle.GetHeight()) / FontRounding
            End If
            If Layout.SmallCalendars.Count <> 0 Then
                Set sm = Layout.SmallCalendars(1)
                .smBodyFont.Size = AdjustSize(8 * FontRounding, 350000, sm.rcClient.GetHeight()) / FontRounding
                .smBodyHighFont.Size = .smBodyFont.Size
                .smHeadFont.Size = AdjustSize(8 * FontRounding, 350000, sm.rcClient.GetHeight()) / FontRounding
                .smHeadHighFont.Size = .smHeadFont.Size
                .smTitleFont.Size = AdjustSize(10 * FontRounding, 350000, sm.rcClient.GetHeight()) / FontRounding
            End If
        End With
    End With
End Sub

Public Function ToStr(ByVal v As Double) As String
    Dim s As String
    s = Trim$(str$(Abs(v)))
    If Left$(s, 1) = "." Then s = "0" & s
    If v < 0 Then s = "-" & s
    ToStr = s
End Function

Public Function ToVal(ByVal v As String) As Double
    Dim s As String
    s = Trim$(v)
    If s <> "" Then
        ToVal = Val(s)
    Else
        ToVal = 0
    End If
End Function

Public Function FromInches(ByVal v As Double) As Double
    FromInches = v * 254000
End Function

Public Function FromMillimeters(ByVal v As Double) As Double
    FromMillimeters = v * 10000
End Function

Public Function FromPoints(ByVal v As Double) As Double
    FromPoints = v * 254000 / 72
End Function

Public Function FromUnit(v As Double) As Double
    Select Case Settings.Unit
        Case 0 'in
            FromUnit = FromInches(v)
        Case 1 'mm
            FromUnit = FromMillimeters(v)
        Case 2 'pt
            FromUnit = FromPoints(v)
        Case Else
            FromUnit = 0
    End Select
End Function

Public Function ToUnit(v As Double) As Double
    Select Case Settings.Unit
        Case 0 'in
            ToUnit = v / 254000
        Case 1 'mm
            ToUnit = v / 10000
        Case 2 'pt
            ToUnit = v * 72 / 254000
        Case Else
            ToUnit = 0
    End Select
End Function

Public Function GetFloatStep() As Long
    Dim n As Long
    Select Case Settings.Unit
        Case 0 'in
            n = FromInches(0.05)
        Case 1 'mm
            n = FromMillimeters(1)
        Case 2 'pt
            n = FromPoints(1)
        Case Else
            n = 0
    End Select
    GetFloatStep = n
End Function

Sub ShowError(Optional Text As String)
    If Text <> "" Then
        MsgBox Text & vbCr & "Error #" & Err.Number & vbCr & Err.Description, vbCritical, "Error"
    Else
        MsgBox "Unexpected Error occured: #" & Err.Number & vbCr & Err.Description, vbCritical, "Error"
    End If
End Sub

Public Sub LoadLanguages(Optional Dummy As Long)
    Dim v As Variant
    Dim lng As clsLanguage
    Dim str As clsStream, s As String
    Dim n As Long, cnt As Long
    Set Languages = New Collection
    Dim FileName As String
    EnglishMonth(1) = "January"
    EnglishMonth(2) = "February"
    EnglishMonth(3) = "March"
    EnglishMonth(4) = "April"
    EnglishMonth(5) = "May"
    EnglishMonth(6) = "June"
    EnglishMonth(7) = "July"
    EnglishMonth(8) = "August"
    EnglishMonth(9) = "September"
    EnglishMonth(10) = "October"
    EnglishMonth(11) = "November"
    EnglishMonth(12) = "December"
    FileName = Draw.UserDataPath & "cwzLang.ini"
    On Error GoTo ErrHandler1
    Open FileName For Input As #1
    On Error GoTo ErrHandler2
    Line Input #1, s
    cnt = Val(s)
    For n = 1 To cnt
        Line Input #1, s
        Set str = New clsStream
        str.ParseString s
        Set lng = New clsLanguage
        lng.ReadData str
        Languages.Add lng
    Next n
ErrResume:
    Close #1
    If Languages.Count = 0 Then
        v = Array("English;0;January;February;March;April;May;June;July;August;September;October;November;December;Sun;Sunday;Mon;Monday;Tue;Tuesday;Wed;Wednesday;Thu;Thursday;Fri;Friday;Sat;Saturday;0;0", _
                "English (Canada);0;January;February;March;April;May;June;July;August;September;October;November;December;Sun;Sunday;Mon;Monday;Tue;Tuesday;Wed;Wednesday;Thu;Thursday;Fri;Friday;Sat;Saturday;0;6;101;New Year's Day;107;Canada Day;3110;Halloween;1111;Remembrance Day;2512;Christmas Day;2612;Boxing Day", _
                "English (UK);0;January;February;March;April;May;June;July;August;September;October;November;December;Sun;Sunday;Mon;Monday;Tue;Tuesday;Wed;Wednesday;Thu;Thursday;Fri;Friday;Sat;Saturday;0;5;101;New Year's Day;3110;Halloween;511;Guy Fawkes Day;2512;Christmas Day;2612;Boxing Day", _
                "English (USA);0;January;February;March;April;May;June;July;August;September;October;November;December;Sun;Sunday;Mon;Monday;Tue;Tuesday;Wed;Wednesday;Thu;Thursday;Fri;Friday;Sat;Saturday;0;5;101;New Year's Day;1402;Valentine's Day;407;Independence Day;3110;Halloween;2512;Christmas Day", _
                "Danish;0;Januar;Februar;Marts;April;Maj;Juni;Juli;August;September;Oktober;November;December;sø;Søndag;ma;Mandag;ti;Tirsdag;on;Onsdag;to;Torsdag;fr;Fredag;lø;Lørdag;1;0", _
                "Dutch;0;Januari;Februari;Maart;April;Mei;Juni;Juli;Augustus;September;Oktober;November;December;zo;Zondag;ma;Maandag;di;Dinsdag;wo;Woensdag;do;Donderdag;vr;Vrijdag;za;Zaterdag;1;0", _
                "Finnish;0;Tammikuu;Helmikuu;Maaliskuu;Huhtikuu;Toukokuu;Kesäkuu;Heinäkuu;Elokuu;Syyskuu;Lokakuu;Marraskuu;Joulukuu;su;Sunnuntai;ma;Maanantai;ti;Tiistai;ke;Keskiviikko;to;Torstai;pe;Perjantai;la;Lauantai;1;0", _
                "French;0;Janvier;Février;Mars;Avril;Mai;Juin;Juillet;Août;Septembre;Octobre;Novembre;Décembre;Dim.;Dimanche;Lun.;Lundi;Mar.;Mardi;Mer.;Mercredi;Jeu.;Jeudi;Ven.;Vendredi;Sam.;Samedi;0;0", _
                "German;0;Januar;Februar;März;April;Mai;Juni;Juli;August;September;Oktober;November;Dezember;so;Sonntag;mo;Montag;di;Dienstag;mi;Mittwoch;do;Donnerstag;fr;Freitag;sa;Samstag;1;0", _
                "Italian;0;Gennaio;Febbraio;Marzo;Aprile;Maggio;Giugno;Luglio;Agosto;Settembre;Ottobre;Novembre;Dicembre;Dom;Domenica;Lun;Lunedì;Mar;Martedì;Mer;Mercoledì;Gio;Giovedì;Ven;Venerdì;Sab;Sabato;0;0", _
                "Norwegian;0;Januar;Februar;Mars;April;Mai;Juni;Juli;August;September;Oktober;November;Desember;sø;Søndag;ma;Mandag;ti;Tirsdag;on;Onsdag;to;Torsdag;fr;Fredag;lø;Lørdag;1;0", _
                "Portuguese;0;Janeiro;Fevereiro;Março;Abril;Maio;Junho;Julho;Agosto;Setembro;Outubro;Novembro;Dezembro;Dom;Domingo;Seg;Segunda-feira;Ter;Terça-feira;Qua;Quarta-feira;Qui;Quinta-feira;*****;Sexta-feira;Sáb;Sábado;0;0", _
                "Russian;204;ßíâàðü;Ôåâðàëü;Ìàðò;Àïðåëü;Ìàé;Èþíü;Èþëü;Àâãóñò;Ñåíòÿáðü;Îêòÿáðü;Íîÿáðü;Äåêàáðü;âñ;Âîñêðåñåíüå;ïí;Ïîíåäåëüíèê;âò;Âòîðíèê;ñð;Ñðåäà;÷ò;×åòâåðã;ïò;Ïÿòíèöà;ñá;Ñóááîòà;1;0", _
                "Spanish;0;Enero;Febrero;Marzo;Abril;Mayo;Junio;Julio;Agosto;Septiembre;Octubre;Noviembre;Diciembre;Dom;Domingo;Lun;Lunes;Mar;Martes;Mié;Miércoles;Jue;Jueves;Vie;Viernes;Sáb;Sábado;1;0", _
                "Swedish;0;Januari;Februari;Mars;April;Maj;Juni;Juli;Augusti;September;Oktober;November;December;sö;Söndag;må;Måndag;ti;Tisdag;on;Onsdag;to;Torsdag;fr;Fredag;lö;Lördag;1;0", _
                "Ukrainian;204;ѳ÷åíü;Ëþòèé;Áåðåçåíü;Êâ³òåíü;Òðàâåíü;×åðâåíü;Ëèïåíü;Ñåðïåíü;Âåðåñåíü;Æîâòåíü;Ëèñòîïàä;Ãðóäåíü;íä;Íåä³ëëÿ;ïí;Ïîíåä³ëîê;âò;³âòîðîê;ñð;Ñåðåäà;÷ò;×åòâåð;ïò;Ï'ÿòíèöÿ;ñá;Ñóáîòà;1;0")

        For n = LBound(v) To UBound(v)
            Set str = New clsStream
            str.ParseString v(n)
            Set lng = New clsLanguage
            lng.ReadData str
            Languages.Add lng
        Next n
    End If
    Exit Sub
ErrHandler2:
    ShowError "Error reading language file: " & FileName
ErrHandler1:
    Resume ErrResume
End Sub

Public Sub SaveLanguages(Optional Dummy As Long)
    Dim str As clsStream
    Dim Lang As clsLanguage
    Dim FileName As String
    FileName = Draw.UserDataPath & "cwzLang.ini"
    On Error GoTo ErrHandler
    Open FileName For Output As #1
    Print #1, Languages.Count
    For Each Lang In Languages
        Set str = New clsStream
        Lang.WriteData str
        Print #1, str.BuildString()
    Next Lang
ErrResume:
    Close #1
    Exit Sub
ErrHandler:
    ShowError "Error writing language file: " & FileName
    Resume ErrResume
End Sub

Public Sub LoadFormats(Optional Dummy As Long)
    Dim fmt As clsFormatting
    Dim str As clsStream, s As String
    Dim n As Long, cnt As Long
    Set Formats = New Collection
    Dim FileName As String
    FileName = Draw.UserDataPath & "cwzStyles.ini"
    On Error GoTo ErrHandler1
    Open FileName For Input As #1
    On Error GoTo ErrHandler2
    Line Input #1, s
    cnt = Val(s)
    For n = 1 To cnt
        Line Input #1, s
        Set str = New clsStream
        str.ParseString s
        Set fmt = New clsFormatting
        fmt.ReadData str
        Formats.Add fmt
    Next n
ErrResume:
    Close #1
    Exit Sub
ErrHandler2:
    ShowError "Error reading style file: " & FileName
ErrHandler1:
    Resume ErrResume
End Sub

Public Sub SaveFormats(Optional Dummy As Long)
    Dim str As clsStream
    Dim fmt As clsFormatting
    Dim FileName As String
    FileName = Draw.UserDataPath & "cwzStyles.ini"
    On Error GoTo ErrHandler
    Open FileName For Output As #1
    Print #1, Formats.Count
    For Each fmt In Formats
        Set str = New clsStream
        fmt.WriteData str
        Print #1, str.BuildString()
    Next fmt
ErrResume:
    Close #1
    Exit Sub
ErrHandler:
    ShowError "Error writing style file: " & FileName
    Resume ErrResume
End Sub

Public Function FindLanguage(lng As clsLanguage) As Long
    Dim p As clsLanguage, n As Long
    n = 0
    For Each p In Languages
        If lng Is p Then
            FindLanguage = n
            Exit Function
        End If
        n = n + 1
    Next p
    FindLanguage = 0
End Function

Private Sub AddPageMM(Name As String, sx As Single, sy As Single)
    Dim p As New clsPage
    p.Width = FromMillimeters(sx)
    p.Height = FromMillimeters(sy)
    p.Name = Name
    Pages.Add p
End Sub

Private Sub AddPageIN(Name As String, sx As Single, sy As Single)
    Dim p As New clsPage
    p.Width = FromInches(sx)
    p.Height = FromInches(sy)
    p.Name = Name
    Pages.Add p
End Sub

Public Sub LoadPages(Optional Dummy As Long)
    Dim OldUnit As cdrUnit
    Dim p As clsPage
    Dim ps As PageSize
    OldUnit = Application.Unit
    Application.Unit = cdrMillimeter
    Set Pages = New Collection
    For Each ps In Application.PageSizes
        AddPageMM ps.Name, ps.Width, ps.Height
    Next ps
    Application.Unit = OldUnit
    If Pages.Count = 0 Then
        AddPageIN "Letter", 8.5, 11
        AddPageMM "A4", 210, 297
    End If
End Sub

Public Sub ShowPreview(pImage As MSFORMS.Image, SmallOnly As Boolean)
    Dim m As clsMonth
    Dim Margin As Long
    Dim hdc As LongPtr, xDpi As Long, yDpi As Long
    Dim sx As Long, sy As Long
    Dim cx As Long, cy As Long
    Dim bx As Double, by As Double
    Dim pdc As New clsPaintDC
    Dim rc As New clsRect, BackColor As Long
    Dim Layout As New clsLayout, SmallCalendar As clsSmallCalendar
    Dim s As String
    On Error GoTo ErrHandler
    s = Draw.CorelScriptTools.GetTempFolder() & "~Temp.bmp"
    Set m = Settings.GetSelMonth(Settings.PreviewPage)
    Layout.SetLayout Settings.LayoutType, m
    hdc = GetDC(0)
    xDpi = GetDeviceCaps(hdc, LOGPIXELSX)
    yDpi = GetDeviceCaps(hdc, LOGPIXELSY)
    ReleaseDC 0, hdc
    If SmallOnly And Layout.SmallCalendars.Count <> 0 Then
        Set SmallCalendar = Layout.SmallCalendars(1)
        rc.CopyAssign SmallCalendar.rcClient
        Margin = 5
    Else
        rc.Assign Settings.PageOrgX, Settings.PageOrgY, Settings.PageWidth, Settings.PageHeight
        Set SmallCalendar = Nothing
        Margin = 1
    End If
    sx = xDpi * pImage.Width / 72 - 2 - 2 * Margin - 1
    sy = yDpi * pImage.Height / 72 - 2 - 2 * Margin - 1
    bx = rc.GetWidth()
    by = rc.GetHeight()
    If bx = 0 Then bx = 1
    If by = 0 Then by = 1
    If bx * sy / by > sx Then
        cy = by * sx / bx
        cx = sx
    Else
        cx = bx * sy / by
        cy = sy
    End If
    With pdc
        .ScaleX = cx / bx
        .ScaleY = -cy / by
        .mPreview = True
        .OffsetX = (sx - cx) / 2 + Margin
        .OffsetY = (sy - cy) / 2 + Margin
        .OrgX = rc.nLeft
        .OrgY = rc.nTop
    End With
    If SmallCalendar Is Nothing Then
        BackColor = RGB(128, 128, 128)
        pdc.hdc = BeginImage(sx + 2 * Margin + 1, sy + 2 * Margin + 1, BackColor)
        pdc.DrawFilledRectangle rc, cWhite
        pdc.DrawHollowRectangle rc, cLtGray
        Layout.Draw pdc
    Else
        BackColor = vbWhite
        pdc.hdc = BeginImage(sx + 2 * Margin + 1, sy + 2 * Margin + 1, BackColor)
        SmallCalendar.Draw pdc
    End If
    EndImage s
    pImage.Picture = LoadPicture(s)
    pImage.BackColor = BackColor
    Kill s
ExitSub:
    Exit Sub
ErrHandler:
    ShowError
    Resume ExitSub
End Sub

Public Sub IntGenerateCalendar(Optional Dummy As Long)
    Dim doc As Document
    Dim m As New clsMonth, n As Long
    Dim pdc As New clsPaintDC
    Dim rc As New clsRect
    Dim Layout As New clsLayout
    Dim s As String, bFirst As Boolean
    With pdc
        .ScaleX = 1
        .ScaleY = 1
        .mPreview = False
        .OffsetX = Settings.PageOrgX
        .OffsetY = Settings.PageOrgY
        .OrgX = 0
        .OrgY = 0
        Set .sr = New ShapeRange
    End With
    On Error GoTo ErrHandler1
    If Settings.mInPlace Then
        Set doc = Draw.ActiveDocument
    Else
        Set doc = Draw.CreateDocument()
    End If
    On Error GoTo ErrHandler2
    doc.SaveSettings
    doc.ResetSettings
    doc.Unit = cdrTenthMicron
    doc.PreserveSelection = False
    Draw.EventsEnabled = False
    Draw.Optimization = True
    If Not Settings.mInPlace Then
        doc.MasterPage.SetSize Settings.PageWidth, Settings.PageHeight
    End If
    bFirst = True
    If Settings.LayoutType < 8 And Not Settings.mInRect Then
        ' Month calendars
        For n = 1 To 12
            If Settings.Month(n) Then
                doc.BeginCommandGroup "Calendar (" & EnglishMonth(n) & " " & Settings.Year & ")"
                If Not bFirst Then
                    If Settings.mInPlace Then
                        doc.AddPagesEx 1, Settings.PageWidth, Settings.PageHeight
                    Else
                        doc.AddPages 1
                    End If
                End If
                m.Init n, Settings.Year
                Set pdc.Layer = doc.ActiveLayer
                Set pdc.VirtualLayer = doc.TreeManager.VirtualLayer
                Layout.SetLayout Settings.LayoutType, m
                Layout.Draw pdc
                doc.EndCommandGroup
                bFirst = False
            End If
        Next n
    End If
    If bFirst Then
        m.Init Settings.GetFirstSelectedMonth(), Settings.Year
        Set pdc.Layer = doc.ActiveLayer
        Set pdc.VirtualLayer = doc.TreeManager.VirtualLayer
        Layout.SetLayout Settings.LayoutType, m
        doc.BeginCommandGroup "Calendar (" & Settings.Year & ")"
        Layout.Draw pdc
        doc.EndCommandGroup
    End If
ErrResume:
    Draw.EventsEnabled = True
    Draw.Optimization = False
    doc.RestoreSettings
    Draw.ActiveWindow.Refresh
    Draw.Refresh
ExitSub:
    Exit Sub
ErrHandler2:
    ShowError
    Resume ErrResume
ErrHandler1:
    ShowError
    Resume ExitSub
End Sub

Public Sub GenerateCalendar(Optional Dummy As Long)
    IntGenerateCalendar Dummy
    MsgBox "Finished generating the calendar", vbInformation
End Sub

 

Javascript Online Compiler

Write, Run & Share Javascript code online using OneCompiler's JS online compiler for free. It's one of the robust, feature-rich online compilers for Javascript language. Getting started with the OneCompiler's Javascript editor is easy and fast. The editor shows sample boilerplate code when you choose language as Javascript and start coding.

About Javascript

Javascript(JS) is a object-oriented programming language which adhere to ECMA Script Standards. Javascript is required to design the behaviour of the web pages.

Key Features

  • Open-source
  • Just-in-time compiled language
  • Embedded along with HTML and makes web pages alive
  • Originally named as LiveScript.
  • Executable in both browser and server which has Javascript engines like V8(chrome), SpiderMonkey(Firefox) etc.

Syntax help

STDIN Example

var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

rl.on('line', function(line){
    console.log("Hello, " + line);
});

variable declaration

KeywordDescriptionScope
varVar is used to declare variables(old way of declaring variables)Function or global scope
letlet is also used to declare variables(new way)Global or block Scope
constconst is used to declare const values. Once the value is assigned, it can not be modifiedGlobal or block Scope

Backtick Strings

Interpolation

let greetings = `Hello ${name}`

Multi line Strings

const msg = `
hello
world!
`

Arrays

An array is a collection of items or values.

Syntax:

let arrayName = [value1, value2,..etc];
// or
let arrayName = new Array("value1","value2",..etc);

Example:

let mobiles = ["iPhone", "Samsung", "Pixel"];

// accessing an array
console.log(mobiles[0]);

// changing an array element
mobiles[3] = "Nokia";

Arrow functions

Arrow Functions helps developers to write code in concise way, it’s introduced in ES6.
Arrow functions can be written in multiple ways. Below are couple of ways to use arrow function but it can be written in many other ways as well.

Syntax:

() => expression

Example:

const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const squaresOfEvenNumbers = numbers.filter(ele => ele % 2 == 0)
                                    .map(ele => ele ** 2);
console.log(squaresOfEvenNumbers);

De-structuring

Arrays

let [firstName, lastName] = ['Foo', 'Bar']

Objects

let {firstName, lastName} = {
  firstName: 'Foo',
  lastName: 'Bar'
}

rest(...) operator

 const {
    title,
    firstName,
    lastName,
    ...rest
  } = record;

Spread(...) operator

//Object spread
const post = {
  ...options,
  type: "new"
}
//array spread
const users = [
  ...adminUsers,
  ...normalUsers
]

Functions

function greetings({ name = 'Foo' } = {}) { //Defaulting name to Foo
  console.log(`Hello ${name}!`);
}
 
greet() // Hello Foo
greet({ name: 'Bar' }) // Hi Bar

Loops

1. If:

IF is used to execute a block of code based on a condition.

Syntax

if(condition){
    // code
}

2. If-Else:

Else part is used to execute the block of code when the condition fails.

Syntax

if(condition){
    // code
} else {
    // code
}

3. Switch:

Switch is used to replace nested If-Else statements.

Syntax

switch(condition){
    case 'value1' :
        //code
        [break;]
    case 'value2' :
        //code
        [break;]
    .......
    default :
        //code
        [break;]
}

4. For

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement){  
//code  
} 

5. While

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while (condition) {  
  // code 
}  

6. Do-While

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {  
  // code 
} while (condition); 

Classes

ES6 introduced classes along with OOPS concepts in JS. Class is similar to a function which you can think like kind of template which will get called when ever you initialize class.

Syntax:

class className {
  constructor() { ... } //Mandatory Class method
  method1() { ... }
  method2() { ... }
  ...
}

Example:

class Mobile {
  constructor(model) {
    this.name = model;
  }
}

mbl = new Mobile("iPhone");