Imports System.IO
#Region "C/C++ types in VB.NET"
Imports qword = System.UInt64
Imports dword = System.UInt32
Imports float = System.Single
Imports word = System.UInt16
Imports bool = System.Boolean
#End Region
Partial Public Class NJCM
    Partial Public Class IO
        Partial Public Class ExBinaryReader
            Inherits System.IO.BinaryReader
            Sub New(ByVal A As Stream)
                MyBase.New(A)
            End Sub
            Sub New(ByVal A As Stream, ByVal B As System.Text.Encoding)
                MyBase.New(A, B)
            End Sub
            Sub New(ByVal Buffer() As Byte)
                MyBase.New(New MemoryStream(Buffer), System.Text.Encoding.ASCII)
            End Sub
            Public Function Readdword() As dword
                Return Me.ReadUInt32
            End Function
            Public Function Readfloat() As float
                Return Me.ReadSingle
            End Function
            Public Function ReadXYZ() As Types.XYZCoord
                Return New Types.XYZCoord(Me.ReadSingle, Me.ReadSingle, Me.ReadSingle)
            End Function
            Private Function ReadABC() As Types.XYZCoord
                Dim c As Double = 0.005493164
                Dim t1 As New Types.XYZCoord
                With t1
                    .X = (Me.Readdword And &HFFFF) * c
                    .Y = (Me.Readdword And &HFFFF) * c
                    .Z = (Me.Readdword And &HFFFF) * c
                End With
                Return t1
            End Function
            Public Function ReadNode() As Types.Node
                Return New Types.Node(Me.Readdword, Me.Readdword, Me.ReadXYZ, Me.ReadABC, Me.ReadXYZ, Me.Readdword, Me.Readdword)
            End Function
            Public Function ReadModel()
                Return New Types.Model(Me.ReadUInt32, Me.ReadUInt32, Me.ReadXYZ, Me.ReadSingle)
            End Function
            Public Function ReadRGBA() As Types.RGBA
                Return New Types.RGBA((Me.ReadByte / 255), (Me.ReadByte / 255), (Me.ReadByte / 255), (Me.ReadByte / 255))
            End Function
            Public Function ReadARGB() As Types.RGBA
                Dim tb As Single = Me.ReadByte / 255
                Dim tg As Single = Me.ReadByte / 255
                Dim tr As Single = Me.ReadByte / 255
                Dim ta As Single = Me.ReadByte / 255
                Return New Types.RGBA(tr, tg, tb, ta)
            End Function
            Public Function ReadChunk() As Types.Chunk
                Return New Types.Chunk(Me.ReadByte, Me.ReadByte)
            End Function
            Public Function ReadNJHeader() As Types.NJHeader
                Dim u As UInteger = 0
                Dim v As UInteger = Me.Position
                u = Me.ReadUInt32
                If u <> 0 Then
                    Me.Seek(v, SeekOrigin.Begin)
                    Return New Types.NJHeader(System.Text.Encoding.ASCII.GetString(Me.ReadBytes(4)), Me.ReadUInt32)
                Else
                    Return New Types.NJHeader("STOP", 0)
                End If
            End Function
            Public Sub Seek(ByVal a As Integer, ByVal b As System.IO.SeekOrigin)
                Me.BaseStream.Seek(a, b)
            End Sub
            Public Function Position() As UInteger
                Position = Me.BaseStream.Position
            End Function
            Public Function Length() As UInteger
                Length = Me.BaseStream.Length
            End Function
        End Class
        Partial Public Class ExBinaryWriter
            Inherits System.IO.BinaryWriter
            Sub New(ByVal A As Stream)
                MyBase.New(A)
            End Sub
            Sub New(ByVal A As Stream, ByVal B As System.Text.Encoding)
                MyBase.New(A, B)
            End Sub
            Sub New(ByVal Buffer() As Byte)
                MyBase.New(New MemoryStream(Buffer), System.Text.Encoding.ASCII)
            End Sub
            Sub WriteXYZ(ByVal A As Types.XYZCoord)
                Me.Write(A.X)
                Me.Write(A.Y)
                Me.Write(A.Z)
            End Sub
            Sub WriteABC(ByVal a As Types.XYZCoord)
                Me.Write(toBAMS(a.X))
                Me.Write(toBAMS(a.Y))
                Me.Write(toBAMS(a.Z))
            End Sub
            Sub WriteNode(ByVal a As Types.Node)
                Me.Write(a.Flags)
                Me.Write(a.Model)
                Me.WriteXYZ(a.Translate)
                Me.WriteABC(a.Rotate)
                Me.WriteXYZ(a.Scale)
                Me.Write(a.Child)
                Me.Write(a.Sibling)
            End Sub
            Sub WriteRGBA(ByVal a As Types.RGBA)
                Me.Write(CType(Int(a.B * 255), Byte))
                Me.Write(CType(Int(a.G * 255), Byte))
                Me.Write(CType(Int(a.R * 255), Byte))
                Me.Write(CType(Int(a.A * 255), Byte))
            End Sub
            Sub WriteARGB(ByVal a As Types.RGBA)
                Me.Write(CType(Int(a.B * 255), Byte))
                Me.Write(CType(Int(a.G * 255), Byte))
                Me.Write(CType(Int(a.R * 255), Byte))
                Me.Write(CType(Int(a.A * 255), Byte))
            End Sub
            Sub WriteChunk(ByVal a As Types.Chunk)
                Me.Write(a.type)
                Me.Write(a.flag)
            End Sub
            Sub WriteNJHeader(ByVal a As Types.NJHeader)
                Me.Write(MakeBytes(a.ID))
                Me.Write(a.Nx)
            End Sub
            Public Function Position() As UInteger
                Position = Me.BaseStream.Position
            End Function
            Public Function Length() As UInteger
                Length = Me.BaseStream.Length
            End Function
            Private Function toBAMS(ByVal q As Single) As UInt32
                Dim t As UInteger = Int(q * &H65536)
                If BitTest(t, 15) Then t = &HFFFF0000 Or t
                Return t
            End Function
        End Class
    End Class
End Class
