'//////////////////////////////////////////////////////////////////////////////
'//
'//  Copyright 2025 Autodesk, Inc.  All rights reserved.
'//
'//  Use of this software is subject to the terms of the Autodesk license 
'//  agreement provided at the time of installation or download, or which 
'//  otherwise accompanies this software in either electronic or hard copy form.   
'//
'//////////////////////////////////////////////////////////////////////////////
'

Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry

Imports AcadmAuto
Imports SymBBAuto
Imports AcadmAuto.McadObjectType
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common

Public Class Notefrm
    Dim note As McadNote
    Dim notestd As McadNoteStandard
    Dim acmApp As AcadmAuto.AcadmApplication
    Dim acadApp As AcadApplication = Library.COM.getActiveObject("AutoCAD.Application.26")
    Dim activeDoc As AcadDocument = acadApp.ActiveDocument

    Private oldtemplatename As String
    Private first As Boolean = False
    Public display As Boolean = True
    Private notetext As String

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        acmApp = activeDoc.Application.GetInterfaceObject("AcadmAuto.AcadmApplication.27")
        Dim util As McadUtility
        util = acmApp.ActiveDocument.Utility

        Dim attachPt(0 To 2) As Double
        Dim attachObj As IMcadGeometry = Nothing
        Dim pick As McadPick

        'Allow user to pick on a object in modelspace
        Try
            pick = util.Pick("select object to attach:", mcGeometry)

            'Get selected attached object
            attachObj = util.GetObjectFromPick(pick)

            'Get pick point
            Dim pickPt As GEAuto.GePoint
            pickPt = pick.PickPoint
            attachPt(0) = pickPt.X
            attachPt(1) = pickPt.Y
            attachPt(2) = pickPt.Z
        Catch ex As System.SystemException
        End Try

        'Get leader start point
        Dim startPt As Object = Nothing
        Try
            startPt = activeDoc.Utility.GetPoint(, "Start Point: ")
        Catch ex As SystemException
        End Try
        If (startPt Is Nothing) Then
            display = False
            Exit Sub
        End If

        Dim leaderPts(5) As Double
        leaderPts(0) = startPt(0)
        leaderPts(1) = startPt(1)
        leaderPts(2) = startPt(2)

        'Get leader end point
        Dim endPt As Object = Nothing
        Try
            endPt = activeDoc.Utility.GetPoint(, "Next Point: ")
        Catch ex As SystemException
        End Try
        If (endPt Is Nothing) Then
            display = False
            Exit Sub
        End If

        leaderPts(3) = endPt(0)
        leaderPts(4) = endPt(1)
        leaderPts(5) = endPt(2)

        'Create Note symbol
        note = activeDoc.ModelSpace.AddCustomObject("AmdtNote")

        'Set the properties of this Note symbol to the default values
        note.SetToDefaults()

        'Specifies the note to automatically adjusted to the default position on the leader
        note.Origin = attachPt

        'Add leader
        note.AddLeader(leaderPts)

        'Create note text as "Test".
        'This method need to be called after adding leader and before setting content of note text
        note.CreateNoteText("")

        'Attach symbol to object
        If Not (attachObj Is Nothing) Then
            note.AttachGeometry(attachObj, attachPt)
        End If

        'initialize Notefrm first page according to Note symbol setting.
        InitializeNotefrm()

        'Regen note symbol
        note.Update()
        activeDoc.Regen(AcRegenType.acActiveViewport)
    End Sub

    Private Sub InitializeNotefrm()
        first = True

        'initialize text justification
        Dim textAlign As McadAlignmentType = note.TextAlignment
        cbTextJust.SelectedIndex = textAlign

        'get note standard
        notestd = GetNoteStd()

        'Set default leader justification
        Dim defaultAttPt As McadNoteAttachPointType
        defaultAttPt = notestd.LeaderAttachPoint
        cbLeaderJust.SelectedIndex = AttachPointIndex(defaultAttPt)
        note.LeaderAttachPoint = defaultAttPt

        'Set default landing
        Dim defaultLanding As Boolean
        defaultLanding = notestd.Landing
        ckLanding.Checked = defaultLanding
        note.Landing = defaultLanding

        'Get feature type for the object attached to note
        Dim grouptype() As Integer
        grouptype = notestd.GetFeatureTypes(note)
        notestd.SetCompatibilityCondition(grouptype)

        'Set list of template groups
        Dim i As Integer
        Dim groupname As String
        If Not grouptype Is Nothing Then
            For i = LBound(grouptype) To UBound(grouptype)
                'parse integer to string for template group name
                groupname = TemplateGroupName(grouptype(i))
                cbTemplateGroups.Items.Add(groupname)
            Next i

            'Display the first template group
            groupname = TemplateGroupName(grouptype(0))
        Else
            groupname = TemplateGroupName(McadNoteTemplateGroupType.sbOther)
        End If

        'Add other templates group
        cbTemplateGroups.Items.Add(TemplateGroupName(McadNoteTemplateGroupType.sbOther))

        cbTemplateGroups.SelectedItem = groupname

        'get first template group
        Dim templateGroup1 As Object
        templateGroup1 = notestd.GetTemplateGroup(0, True)

        Dim tempNames() As String
        tempNames = notestd.GetAllTemplates(templateGroup1)

        If VarType(tempNames) <> vbEmpty And (Not tempNames Is Nothing) Then
            ' Display the note text for the first template 
            Dim templatevalue As String
            templatevalue = notestd.GetTemplateValue(grouptype, tempNames(0))
            note.NoteText = templatevalue
        End If
        txtNoteText.Text = note.NoteText

    End Sub

    Private Function AttachPointIndex(ByVal val As McadNoteAttachPointType) As Integer
        Select Case val
            Case McadNoteAttachPointType.sbMiddleTopLine
                AttachPointIndex = 0
            Case McadNoteAttachPointType.sbBottomTopLine
                AttachPointIndex = 1
            Case McadNoteAttachPointType.sbMiddleText
                AttachPointIndex = 2
            Case McadNoteAttachPointType.sbMiddleBottomLine
                AttachPointIndex = 3
            Case McadNoteAttachPointType.sbBottomText
                AttachPointIndex = 4
            Case McadNoteAttachPointType.sbTopLineRefLine
                AttachPointIndex = 5
            Case McadNoteAttachPointType.sbUnderlineAllText
                AttachPointIndex = 6
            Case Else
                AttachPointIndex = 0
        End Select
    End Function

    Private Function AttachPointType(ByVal index As Integer) As McadNoteAttachPointType
        Select Case index
            Case 0
                AttachPointType = McadNoteAttachPointType.sbMiddleTopLine
            Case 1
                AttachPointType = McadNoteAttachPointType.sbBottomTopLine
            Case 2
                AttachPointType = McadNoteAttachPointType.sbMiddleText
            Case 3
                AttachPointType = McadNoteAttachPointType.sbMiddleBottomLine
            Case 4
                AttachPointType = McadNoteAttachPointType.sbBottomText
            Case 5
                AttachPointType = McadNoteAttachPointType.sbTopLineRefLine
            Case 6
                AttachPointType = McadNoteAttachPointType.sbUnderlineAllText
            Case Else
                AttachPointType = McadNoteAttachPointType.sbNoPoint
        End Select
    End Function

    Private Function TemplateGroupName(ByVal index As McadNoteTemplateGroupType) As String
        Select Case index
            Case McadNoteTemplateGroupType.sbHoleDrilled
                TemplateGroupName = "HOLE DRILLED"
            Case McadNoteTemplateGroupType.sbCounterBore
                TemplateGroupName = "HOLE COUNTERBORE"
            Case McadNoteTemplateGroupType.sbCounterSink
                TemplateGroupName = "HOLE COUNTERSINK"
            Case McadNoteTemplateGroupType.sbFillet
                TemplateGroupName = "FILLET"
            Case McadNoteTemplateGroupType.sbChamfer
                TemplateGroupName = "CHAMFER"
            Case McadNoteTemplateGroupType.sbPattern
                TemplateGroupName = "PATTERN"
            Case McadNoteTemplateGroupType.sbPart
                TemplateGroupName = "PART TEMPLATES"
            Case McadNoteTemplateGroupType.sbOther
                TemplateGroupName = "OTHER TEMPLATES"
            Case Else
                TemplateGroupName = ""
        End Select
    End Function

    Private Function TemplateGroupIndex(ByRef groupname As String) As McadNoteTemplateGroupType
        Select Case groupname
            Case "HOLE DRILLED"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbHoleDrilled
            Case "HOLE COUNTERBORE"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbCounterBore
            Case "HOLE COUNTERSINK"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbCounterSink
            Case "FILLET"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbFillet
            Case "CHAMFER"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbChamfer
            Case "PATTERN"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbPattern
            Case "PART TEMPLATES"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbPart
            Case "OTHER TEMPLATES"
                TemplateGroupIndex = McadNoteTemplateGroupType.sbOther
            Case Else
                TemplateGroupIndex = 0
        End Select
    End Function

    Private Function GetNoteStd() As McadNoteStandard
        Dim symmgr As McadSymbolBBMgr
        symmgr = activeDoc.Application.GetInterfaceObject("SymBBAuto.McadSymbolBBMgr.27")

        Dim stdmgr As McadStandardMgr
        stdmgr = symmgr.StandardMgr

        Dim std As McadStandard
        std = stdmgr.CurrentStandard

        GetNoteStd = std.NoteStandard
    End Function

    Private Sub cbTemplateGroups_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbTemplateGroups.SelectedIndexChanged
        Dim groupname As String = cbTemplateGroups.SelectedItem.ToString()
        Dim grouptype(0 To 0) As Integer
        If (VarType(groupname) <> vbEmpty) And (groupname <> "") Then
            grouptype(0) = TemplateGroupIndex(groupname)

            Dim templatenames() As String
            If String.Compare(TemplateGroupName(McadNoteTemplateGroupType.sbOther), groupname, StringComparison.OrdinalIgnoreCase) <> 0 Then
                templatenames = notestd.GetAllTemplates(grouptype)
            Else
                'select other templates group
                templatenames = notestd.GetAllTemplates(Nothing)
            End If

            'Display templates for selected template group
            cbTemplateList.Items.Clear()
            If templatenames Is Nothing Then
                Return
            End If

            Dim i As Integer
            For i = LBound(templatenames) To UBound(templatenames)
                cbTemplateList.Items.Add(templatenames(i))
            Next i
        End If
    End Sub

    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        note.NoteText = notetext
        note.LeaderAttachPoint = AttachPointType(cbLeaderJust.SelectedIndex)
        note.TextAlignment = cbTextJust.SelectedIndex
        note.Landing = ckLanding.Checked
        Me.Close()
    End Sub

    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        'set default template name
        Dim index As Integer
        index = 1
        Dim templatename As String = "TEMPLATE_" + index.ToString()
        While existed(templatename)
            index = index + 1
            templatename = "TEMPLATE_" + index.ToString()
        End While

        cbTemplateList.Items.Add(templatename)
        Dim lastindex As Integer = cbTemplateList.Items.Count - 1

        'get selected template group
        Dim groupname As String = cbTemplateGroups.SelectedItem.ToString()
        Dim grouptype(0 To 0) As Integer
        grouptype(0) = TemplateGroupIndex(groupname)

        'add new template to note standard
        If String.Compare(groupname, TemplateGroupName(McadNoteTemplateGroupType.sbOther), StringComparison.OrdinalIgnoreCase) <> 0 Then
            notestd.AddTemplate(grouptype, templatename, txtNoteText.Text, False)
        Else
            notestd.AddTemplate(Nothing, templatename, txtNoteText.Text, False)
        End If

        cbTemplateList.Items(lastindex).Selected = True
        cbTemplateList.Focus()
        cbTemplateList.Items(lastindex).BeginEdit()
    End Sub

    Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click
        If (cbTemplateList.SelectedItems.Count = 0) Then
            Return
        End If

        'get selected template group
        Dim groupname As String = cbTemplateGroups.SelectedItem.ToString()
        Dim grouptype(0 To 0) As Integer
        grouptype(0) = TemplateGroupIndex(groupname)

        'delete selected template from note standard
        If String.Compare(groupname, TemplateGroupName(McadNoteTemplateGroupType.sbOther), StringComparison.OrdinalIgnoreCase) <> 0 Then
            notestd.DeleteTemplate(grouptype, cbTemplateList.SelectedItems(0).Text)
        Else
            notestd.DeleteTemplate(Nothing, cbTemplateList.SelectedItems(0).Text)
        End If

        cbTemplateList.Items.Remove(cbTemplateList.SelectedItems(0))
        If cbTemplateList.Items.Count <> 0 Then
            cbTemplateList.Items(cbTemplateList.Items.Count - 1).Selected = True
            cbTemplateList.Focus()
        End If
    End Sub

    Private Function existed(ByRef templatename As String) As Boolean
        Dim i As Integer
        For i = 0 To cbTemplateList.Items.Count - 1
            If String.Compare(templatename, cbTemplateList.Items(i).Text, StringComparison.OrdinalIgnoreCase) = 0 Then
                existed = True
                Exit Function
            Else
                existed = False
            End If
        Next i

        Return existed
    End Function

    Private Sub btnDefault_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDefault.Click
        If cbTemplateList.SelectedItems.Count = 0 Then
            Return
        End If

        'get selected template group
        Dim groupname As String = cbTemplateGroups.SelectedItem.ToString()
        Dim grouptype(0 To 0) As Integer
        grouptype(0) = TemplateGroupIndex(groupname)

        'set selected template as default in note standard
        If String.Compare(groupname, TemplateGroupName(McadNoteTemplateGroupType.sbOther), StringComparison.OrdinalIgnoreCase) <> 0 Then
            notestd.SetToDefaultTemplate(grouptype, cbTemplateList.SelectedItems(0).Text)
        Else
            notestd.SetToDefaultTemplate(Nothing, cbTemplateList.SelectedItems(0).Text)
        End If

        Dim selitem As System.Windows.Forms.ListViewItem = cbTemplateList.SelectedItems(0)
        cbTemplateList.Items.Remove(selitem)
        cbTemplateList.Items.Insert(0, selitem)
        If cbTemplateList.Items.Count <> 0 Then
            cbTemplateList.Items(0).Selected = True
            cbTemplateList.Focus()
        End If
    End Sub

    Private Sub cbTemplateList_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbTemplateList.SelectedIndexChanged
        If cbTemplateList.SelectedItems.Count = 0 Then
            Return
        End If

        If cbTemplateList.SelectedIndices(0) > cbTemplateList.Items.Count Then
            Return
        End If

        'get the current template value assosiated with selected template name.
        Dim templatename As String = cbTemplateList.SelectedItems(0).Text

        'get selected template group
        Dim groupname As String = cbTemplateGroups.SelectedItem.ToString()
        Dim grouptype(0 To 0) As Integer
        grouptype(0) = TemplateGroupIndex(groupname)

        If (VarType(templatename) <> vbEmpty) And (String.Compare(groupname, TemplateGroupName(McadNoteTemplateGroupType.sbOther), StringComparison.OrdinalIgnoreCase) <> 0) Then
            txtNoteText.Text = notestd.GetTemplateValue(grouptype, templatename)
        Else
            txtNoteText.Text = notestd.GetTemplateValue(Nothing, templatename)
        End If
    End Sub

    Private Sub ckLanding_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ckLanding.CheckedChanged
        If first Then
            first = False
            Return
        End If

        note.Landing = ckLanding.Checked
        note.Update()
        activeDoc.Regen(AcRegenType.acAllViewports)
    End Sub

    Private Sub cbTextJust_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbTextJust.SelectedIndexChanged
        If first Then
            first = False
            Return
        End If

        note.TextAlignment = cbTextJust.SelectedIndex
        note.Update()
        activeDoc.Regen(AcRegenType.acActiveViewport)
    End Sub

    Private Sub cbLeaderJust_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbLeaderJust.SelectedIndexChanged
        If first Then
            first = False
            Return
        End If

        note.LeaderAttachPoint = AttachPointType(cbLeaderJust.SelectedIndex)
        note.Update()
        activeDoc.Regen(AcRegenType.acActiveViewport)
    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        note.Delete()
        Me.Close()
    End Sub

    Private Sub cbTemplateList_AfterLabelEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LabelEditEventArgs) Handles cbTemplateList.AfterLabelEdit
        Dim newname As String = e.Label
        If newname Is Nothing Then
            Return
        End If

        'get selected template group
        Dim groupname As String = cbTemplateGroups.SelectedItem.ToString()
        Dim grouptype(0 To 0) As Integer
        grouptype(0) = TemplateGroupIndex(groupname)

        If Not (existed(newname)) Then
            If String.Compare(groupname, TemplateGroupName(McadNoteTemplateGroupType.sbOther), StringComparison.OrdinalIgnoreCase) <> 0 Then
                notestd.RenameTemplate(grouptype, oldtemplatename, newname)
            Else
                notestd.RenameTemplate(Nothing, oldtemplatename, newname)
            End If
        Else
            MsgBox("Duplicated template name.")
            cbTemplateList.Items(e.Item).Selected = True
            cbTemplateList.Focus()
            cbTemplateList.SelectedItems(0).BeginEdit()
        End If
    End Sub

    Private Sub cbTemplateList_BeforeLabelEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LabelEditEventArgs) Handles cbTemplateList.BeforeLabelEdit
        oldtemplatename = cbTemplateList.SelectedItems(0).Text
    End Sub

    Private Sub txtNoteText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtNoteText.TextChanged
        If first Then
            first = False
            Return
        End If

        notetext = String.Empty
        Dim str As String
        For Each str In txtNoteText.Lines
            notetext += str
        Next

        note.NoteText = notetext
        note.Update()
        activeDoc.Regen(AcRegenType.acActiveViewport)
    End Sub

    Private Sub txtNoteText_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtNoteText.KeyPress
        If e.KeyChar = Microsoft.VisualBasic.ChrW(System.Windows.Forms.Keys.Return) Then
            txtNoteText.SelectedText = "\P"
        End If
    End Sub
End Class
