# This file is a tcltest script to handle FTI icons.
# It covers the following functionalities:
# 1. Create and handle icon objects.
# 2. Create and handle item objects.
# 3. Read and write icon files.
# 4. Usage of static functions.

set scriptDir [file normalize [file join [file dirname [info script]] ".."]]
set auto_path [linsert $auto_path 0 $scriptDir]

package require Tk
package require poFti

package require tcltest
tcltest::configure {*}$argv
source [file join [file dirname [info script]] constraints.tcl]

namespace eval ::io::test {
    namespace import ::tcltest::*

    set outFile "io_write.tga"

    #
    # Test-Suite 1: Create poFti Icon objects.
    #
    test io-1.1 "Create empty Icon" -setup {
        set iconObj [poFti Icon new]
    } -body {
        $iconObj GetNumItems
    } -cleanup {
        $iconObj destroy
    } -result 0

    test io-1.2 "Create Icon and add 1 item" -setup {
        set iconObj [poFti Icon new]
        set itemObj [poFti Item new "Item-1"]
        $iconObj AddItem $itemObj
    } -body {
        $iconObj GetNumItems
    } -cleanup {
        $iconObj destroy
    } -result 1

    test io-1.3 "Create Icon and add an item of each type" -setup {
        set iconObj [poFti Icon new]
        set itemObj1 [poFti Item new "Item-Closedline" "closedline"]
        $iconObj AddItem $itemObj1
        set itemObj2 [poFti Item new "Item-Line" "line"]
        $iconObj AddItem $itemObj2
        set itemObj3 [poFti Item new "Item-Point" "point"]
        $iconObj AddItem $itemObj3
        set itemObj4 [poFti Item new "Item-Polygon" "polygon"]
        $iconObj AddItem $itemObj4
        set itemObj5 [poFti Item new "Item-Polygon" "outlinepolygon"]
        $iconObj AddItem $itemObj5
    } -body {
        set res1 [$iconObj GetNumItems]
        set res2 [$iconObj GetNumItems "closedline"]
        set res3 [$iconObj GetNumItems "line"]
        set res4 [$iconObj GetNumItems "point"]
        set res5 [$iconObj GetNumItems "polygon"]
        set res6 [$iconObj GetNumItems "outlinepolygon"]
        list $res1 $res2 $res3 $res4 $res5 $res6
    } -cleanup {
        $iconObj destroy
    } -result [list 5 1 1 1 1 1]

    test io-1.4 "Create Icon with items and get items back." -setup {
        set iconObj [poFti Icon new]
        set itemObj [poFti Item new "Item-Closedline" "closedline"]
        $iconObj AddItem $itemObj
    } -body {
        set itemObjRet [$iconObj GetItem 0]
        set res [$itemObjRet GetType]
    } -cleanup {
        $iconObj destroy
    } -result "closedline"

    test io-1.5 "Create Icon and add an item of invalid type" -body {
        set iconObj [poFti Icon new]
        set itemObj [poFti Item new "Item-Invalid" "invalidtype"]
    } -returnCodes {
        error
    } -cleanup {
        $iconObj destroy
    } -result "Invalid type \"invalidtype\" specified."

    #
    # Test-Suite 2: Create poFti Item objects.
    #
    test io-2.1 "Create empty Item" -setup {
        set itemObj [poFti Item new "Empty Item"]
    } -body {
        set res1 [$itemObj GetNumVertices]
        set res2 [$itemObj GetName]
        set res3 [$itemObj GetType]
        list $res1 $res2 $res3
    } -cleanup {
        $itemObj destroy
    } -result [list 0 "Empty Item" "line"]

    test io-2.2 "Create Item and add 1 vertex" -setup {
        set itemObj [poFti Item new "Item-1"]
        $itemObj AddVertex 10 20
    } -body {
        $itemObj GetVertex 0
    } -cleanup {
        $itemObj destroy
    } -result [list 10 20]

    test io-2.3 "Create Item and add 2 vertices" -setup {
        set itemObj [poFti Item new "Item-1"]
        $itemObj AddVertices 10 20  30 40
    } -body {
        $itemObj GetVertices
    } -cleanup {
        $itemObj destroy
    } -result [list 10 20  30 40]

    test io-2.4 "Create Item and set type" -setup {
        set itemObj [poFti Item new "Item-1" "polygon"]
    } -body {
        $itemObj GetType
    } -cleanup {
        $itemObj destroy
    } -result "polygon"

    test io-2.5 "Create Item with invalid type" -setup {
    } -body {
        set itemObj [poFti Item new "Item-1" "invalidtype"]
    } -returnCodes {
        error
    } -result "Invalid type \"invalidtype\" specified."

    test io-2.6 "Create Item and set invalid type" -setup {
        set itemObj [poFti Item new "Item-1"]
    } -body {
        $itemObj SetType "invalidtype"
    } -returnCodes {
        error
    } -cleanup {
        $itemObj destroy
    } -result "Invalid type \"invalidtype\" specified."

    test io-2.7 "Create Item and set color number" -setup {
        set itemObj [poFti Item new "Item-1" "polygon"]
        $itemObj SetColor 15
        $itemObj SetOutlineColor 14
    } -body {
        set res1 [$itemObj GetColor]
        set res2 [$itemObj GetOutlineColor]
        list $res1 $res2
    } -cleanup {
        $itemObj destroy
    } -result [list 15 14]

    test io-2.8 "Create Item and set special color number" -setup {
        set itemObj1 [poFti Item new "Item-1" "polygon"]
        set itemObj2 [poFti Item new "Item-2" "outlinepolygon"]
    } -body {
        $itemObj1 SetColor "iconcolor"
        $itemObj2 SetColor "shadowcolor"
        $itemObj2 SetOutlineColor "outlinecolor"
        set res1 [$itemObj1 GetColor]
        set res2 [$itemObj2 GetColor]
        set res3 [$itemObj2 GetOutlineColor]
        list $res1 $res2 $res3
    } -cleanup {
        $itemObj1 destroy
        $itemObj2 destroy
    } -result [list "iconcolor" "shadowcolor" "outlinecolor"]

    test io-2.9 "Create Item and set invalid special color number" -setup {
        set itemObj [poFti Item new "Item-1" "polygon"]
    } -body {
        $itemObj SetColor "invalidcolor"
    } -returnCodes {
        error
    } -cleanup {
        $itemObj destroy
    } -result "Invalid color \"invalidcolor\" specified."

    test io-2.10 "Create Item and set color by RGB" -setup {
        set itemObj [poFti Item new "Item-1" "polygon"]
        $itemObj SetColorRgb 255 0 127
        $itemObj SetOutlineColorRgb 127 0 255
    } -body {
        set res1 [$itemObj GetColor]
        set res2 [$itemObj GetOutlineColor]
        list $res1 $res2
    } -cleanup {
        $itemObj destroy
    } -result [list -81 -84]

    test io-2.11 "Create Item and set color by RGB string" -setup {
        set itemObj [poFti Item new "Item-1" "polygon"]
        $itemObj SetColorRgbString "#FF007F"
        $itemObj SetOutlineColorRgbString "#7F00FF"
    } -body {
        set res1 [$itemObj GetColor]
        set res2 [$itemObj GetOutlineColor]
        list $res1 $res2
    } -cleanup {
        $itemObj destroy
    } -result [list -81 -84]

    test io-2.12 "Create Item and set color by invalid RGB string" -setup {
        set itemObj [poFti Item new "Item-1" "polygon"]
    } -body {
        $itemObj SetColorRgbString ""
    } -returnCodes {
        error
    } -cleanup {
        $itemObj destroy
    } -result "Invalid color string \"\" specified."

    test io-2.13 "Create Item and set outline color by invalid RGB string" -setup {
        set itemObj [poFti Item new "Item-1" "polygon"]
    } -body {
        $itemObj SetOutlineColorRgbString "#asdf"
    } -returnCodes {
        error
    } -cleanup {
        $itemObj destroy
    } -result "Invalid color string \"#asdf\" specified."

    #
    # Test-Suite 3: Read and write poFti Icon files.
    #
    set inFile [file join "testIn" "mediaplayer.closed.fti"]
    set outFile "mediaplayer.closed.fti"

    test io-3.1 "Read and write FTI file $inFile" -setup {
        set iconObj [poFti Icon new]
        $iconObj Read $inFile
    } -body {
        $iconObj Write $outFile
        filesIdent $inFile $outFile
    } -cleanup {
        $iconObj destroy
        file delete -force $outFile
    } -result true

    set inFile [file join "testIn" "8mm.loaded.fti"]
    set outFile "8mm.loaded.fti"

    test io-3.2 "Read and write FTI file $inFile" -setup {
        set iconObj [poFti Icon new]
        $iconObj Read $inFile
    } -body {
        $iconObj Write $outFile
        filesIdent $inFile $outFile
    } -cleanup {
        $iconObj destroy
        file delete -force $outFile
    } -result true

    set inFile [file join "testIn" "empty.fti"]

    test io-3.3 "Read empty FTI file $inFile" -setup {
        set iconObj [poFti Icon new]
    } -body {
        $iconObj Read $inFile
    } -returnCodes {
        error
    } -cleanup {
        $iconObj destroy
    } -result "Icon \"empty\" has no items."

    set inFile [file join "testIn" "line_1vtx.fti"]

    test io-3.4 "Read FTI file $inFile with invalid number of vertices" -setup {
        set iconObj [poFti Icon new]
    } -body {
        $iconObj Read $inFile
    } -returnCodes {
        error
    } -cleanup {
        $iconObj destroy
    } -result "Item \"LineItem\" has invalid number of vertices (1)."

    set inFile [file join "testIn" "polygon_2vtx.fti"]

    test io-3.4 "Read FTI file $inFile with invalid number of vertices" -setup {
        set iconObj [poFti Icon new]
    } -body {
        $iconObj Read $inFile
    } -returnCodes {
        error
    } -cleanup {
        $iconObj destroy
    } -result "Item \"PolygonItem\" has invalid number of vertices (2)."

    #
    # Test-Suite 4: Usage of static functions.
    #
    test io-4.1 "Call GetTypeNames" -body {
        poFti GetTypeNames
    } -result [list "closedline" "line" "polygon" "outlinepolygon" "point"]

    test io-4.2 "Call GetPointSize" -body {
        poFti GetPointSize
    } -result 5

    test io-4.3 "Call GetSpecialColors" -body {
        poFti GetSpecialColors
    } -result [list "iconcolor" 7 "shadowcolor" -67 "outlinecolor" 0]

    test io-4.4 "Call IsSpecialColor with valid color name" -body {
        poFti IsSpecialColor "iconcolor"
    } -result true

    test io-4.5 "Call IsSpecialColor with invalid color name" -body {
        poFti IsSpecialColor "invalidcolor"
    } -result false

    test io-4.6 "Call GetSpecialColorNum with color name iconcolor" -body {
        poFti GetSpecialColorNum "iconcolor"
    } -result 7

    test io-4.7 "Call GetSpecialColorNum with color name shadowcolor" -body {
        poFti GetSpecialColorNum "shadowcolor"
    } -result -67

    test io-4.8 "Call GetSpecialColorNum with color name outlinecolor" -body {
        poFti GetSpecialColorNum "outlinecolor"
    } -result 0

    test io-4.9 "Call GetSpecialColorNum with invalid color name" -body {
        poFti GetSpecialColorNum "invalidcolor"
    } -returnCodes {
        error
    } -result "Invalid color \"invalidcolor\" specified."

    test io-4.10 "Call GetRgbStringFromColor with colorNum" -body {
        poFti GetRgbStringFromColor 0
    } -result "#000000"

    test io-4.11 "Call GetRgbStringFromColor with special color iconcolor" -body {
        poFti GetRgbStringFromColor "iconcolor"
    } -result "#ffffff"

    test io-4.12 "Call GetRgbStringFromColor with special color shadowcolor" -body {
        poFti GetRgbStringFromColor "shadowcolor"
    } -result "#7f7f7f"

    test io-4.13 "Call GetRgbStringFromColor with special color outlinecolor" -body {
        poFti GetRgbStringFromColor "outlinecolor"
    } -result "#000000"
}

tcltest::cleanupTests
namespace delete ::io::test
