# mupdf-basic.test --
#
#	Basic tests.
#

package require TTXN
  # package under test is tclMuPdf 2.4.3
package require tclMuPDF 2.4.3

set thisDir [file dirname [file normalize [info script]]]
set samplesDir [file join $thisDir samples]

tcltest::customMatch listCompare listCompare 
    
    proc listCompare {expected actual} {
        if { [llength $expected] != [llength $actual] } {return false}
        foreach e1 $expected e2 $actual {
            if {$e1 != $e2} {return false}
        }
        return true
    }



Name: libinfo
Description: {print MUPDF info}
Test: {
    mupdf::libinfo
}
Expected: {version 1.24.8}


Name: openpdf
Description: {open a sample pdf}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    info object class $pdf
}
Cleanup: { $pdf quit }
Expected: ::mupdf::Doc

Name: openpdf-non-existent-file
Description: {try to open a non existent file}
Test: {
    set pdf [mupdf::open [file join $samplesDir Missing.pdf]]
}
Expected: error glob "cannot open *"

Name: openpdf-a-wrong-file-txt
Description: {try to open a non-pdf file}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-Wrong.txt]]
}
Expected: error "no objects found"

Name: openpdf-wrong-args-1
Description: {mupdf::open with few args}
Test: {
    set pdf [mupdf::open]
}
Expected: error glob "wrong # args: should be *"

Name: openpdf-wrong-args-2
Description: {mupdf::open with extra args}
Test: {
    set pdf [mupdf::open aaa bbb]
}
Expected: error glob "bad option \"bbb\"*"


#
# --- MUPDF warning-message control ---
# 
Name: warnings-check
Description: {checks on warning-messages and repaired PDF}
Setup: {
	set printMode [mupdf::printwarnings]
puts "*INFO*: please ignore subsequent warning messages; there are expected to be some"
	mupdf::printwarnings true
	set pdf [mupdf::open [file join $samplesDir NeedRepair.pdf]]
}
Test: {
	set was_repaired [$pdf wasrepaired]
	$pdf warnings
	# .. some other ops ..
	$pdf fields
	set has_warnings1 [expr {[$pdf warnings] ne {}}]
puts "*INFO*: end of warning messages"
	$pdf resetwarnings
	set has_warnings2 [expr {[$pdf warnings] ne {}}]
	return [list $was_repaired $has_warnings1 $has_warnings2]
}
Cleanup: { 
	$pdf quit 
	mupdf::printwarnings $printMode
}
Expected: {1 1 0}

Name: warnings-check-2
Description: {checks on warning-messages and non-repaired PDF}
Setup: {
	set printMode [mupdf::printwarnings]
	mupdf::printwarnings true
	set pdf [mupdf::open [file join $samplesDir Hello.pdf]]
}
Test: {
	set was_repaired [$pdf wasrepaired]
	$pdf warnings
	# .. some other ops ..
	$pdf fields
	set has_warnings1 [expr {[$pdf warnings] ne {}}]

	$pdf resetwarnings
	set has_warnings2 [expr {[$pdf warnings] ne {}}]
	return [list $was_repaired $has_warnings1 $has_warnings2]
}
Cleanup: { 
	$pdf quit 
	mupdf::printwarnings $printMode
}
Expected: {0 0 0}

Name: printwarning-nasty
Description: {try to delete the mupdf::_PRINT_WARNINGS and check if it's properly restored}
Setup: {
	set printMode [mupdf::printwarnings]
	mupdf::printwarnings false
}
Test: {
     # do something nasty !!
puts "*INFO*: please ignore subsequent warning messages; there are expected to be some"
    unset mupdf::_PRINT_WARNINGS
	# try to open a bad PDF (this will try to record warning-messages..)
	set pdf [mupdf::open [file join $samplesDir NeedRepair.pdf]]
	$pdf quit
	# you should get some warnings on stderr 
	#  .. including the MuPDF warnings that have been re-enabled
	#     since the missing variables has been restored to true
	# let's see if Tcl var has been recreated
	info exists mupdf::_PRINT_WARNINGS
}
Cleanup: { 
	mupdf::printwarnings $printMode
puts "*INFO*: end of warning messages"
}
Expected: {1}

Name: printwarning-nasty-2
Description: {try to delete the mupdf::_PRINT_WARNINGS and check if it's properly restored}
Setup: {
	set printMode [mupdf::printwarnings]
	mupdf::printwarnings false
}
Test: {
     # do something nasty !!
puts "*INFO*: please ignore subsequent warning messages; there are expected to be some"
    unset mupdf::_PRINT_WARNINGS
	set mode1 [mupdf::printwarnings]
	
    set mupdf::_PRINT_WARNINGS xxx
	set mode2 [mupdf::printwarnings]
puts "*INFO*: end of warning messages"
	return [list $mode1 $mode2]
}
Cleanup: { 
	mupdf::printwarnings $printMode
}
Expected: {true true}


#
# --- tests on document ---
# 

Name: isobject-doc.neg
Description: {isobject on a non-object}
Test: {
    mupdf::isobject "fake-object"
}
Expected: 0

Name: isobject-doc
Description: {isobject}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    mupdf::isobject $pdf
}
Cleanup: {$pdf quit}
Expected: 1

Name: isobject-closed
Description: {isobject on a reference to a closed object}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    $pdf quit
    mupdf::isobject $pdf
}
Expected: 0

Name: classinfo-doc
Description: {get the class of an object}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    mupdf::classinfo $pdf
}
Cleanup: { $pdf quit }
Expected: ::mupdf::Doc

Name: classinfo-doc-closed
Description: {get the type of a closed referenced object}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    $pdf quit
    mupdf::classinfo $pdf
}
Expected: error glob "* does not refer to an object"

Name: classinfo-string
Description: {get type of a non- mupdf-object}
Test: {
    mupdf::classinfo "::mupdf::doc-9999999"
}
Expected: error glob "* does not refer to an object"

Name: documents-0
Description: {get (empty) list of opened documents}
Test: {
    mupdf::documents
}
Expected: {}

Name: documents-1
Description: {get list of opened documents}
Test: {
    set pdf1 [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set L [mupdf::documents]
    list [llength $L] [mupdf::classinfo [lindex $L 0]]
}
Cleanup: {
    $pdf1 quit
}
Expected: {1 ::mupdf::Doc}

Name: documents-2
Description: {get list of opened documents}
Test: {
    set pdf1 [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set pdf2 [mupdf::open [file join $samplesDir Sample-01.pdf]]
    llength [mupdf::documents]
}
Cleanup: {
    $pdf1 quit
    $pdf2 quit
}
Expected: 2

Name: documentnames
Description: {get list of opened documents - full filenames}
Setup: {
    set pdf1 [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set pdf2 [mupdf::open [file join $samplesDir Hello.pdf]]

    set LX {} ;# expected result
    lappend LX [file normalize [file join $samplesDir Sample-01.pdf]]
    lappend LX [file normalize [file join $samplesDir Hello.pdf]]
}
Test: {
    set L [mupdf::documentnames]
    listCompare [lsort $L] [lsort $LX]
}
Cleanup: {
    $pdf1 quit
    $pdf2 quit
}
Expected: true 


#
# -- document's anchors
#

Name: document-anchor-NEG
Description: {get anchor - missing args}
Test: {
    set pdf [mupdf::open [file join $samplesDir Book.pdf]]
    $pdf anchor
}
Cleanup: {
    $pdf quit
}
Expected: error glob "wrong # args: *"

Name: document-anchor-NEG2
Description: {get anchor - wrong anchor name}
Test: {
    set pdf [mupdf::open [file join $samplesDir Book.pdf]]
    $pdf anchor "wrong anchor name"
}
Cleanup: {
    $pdf quit
}
Expected: {-1 0.0 0.0}

Name: document-anchor
Description: {get anchor}
Test: {
    set pdf [mupdf::open [file join $samplesDir Book.pdf]]
	set L {}
	foreach tag {Chapter1 Chapter2 Chapter3} {
		set pxy [$pdf anchor $tag]
	     # just for compare testing: round x y to integers...
	    lassign $pxy pageNum x y
	    set x [expr round($x)]
	    set y [expr round($y)]
		lappend L [list $tag $pageNum $x $y]
	}
	return $L
}
Cleanup: {
    $pdf quit
}
Expected: {{Chapter1 0 0 281} {Chapter2 2 0 303} {Chapter3 3 0 617}}

#
# -- documents and pages
#

Name: document-npages
Description: {get number of pages}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    $pdf npages
}
Cleanup: {
    $pdf quit
}
Expected: 5

Name: ispageopened
Description: {check ispageopened}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set p0 [$pdf getpage 0]
    set p4 [$pdf getpage 4]
    set L {}
    foreach pagenum {0 1 2 3 4} {
        lappend L [$pdf ispageopened $pagenum]
    }
    return $L
}
Cleanup: {
    $pdf quit
}
Expected: {1 0 0 0 1}

Name: document-get-pages
Description: {get a page}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set p0 [$pdf getpage 0]
    set p4 [$pdf getpage 4]
    set L [lsort [$pdf openedpages]]  ;# openedpages returns items in random order
}
Cleanup: {
    $pdf quit
}
Expected: {0 4}

Name: document-get-pages-twice
Description: {get a page, then get it again}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set p0a [$pdf getpage 0]
    $p0a destroy
    set p0b [$pdf getpage 0]
    expr { $p0a ne $p0b }    
}
Cleanup: {
    $pdf quit
}
Expected: 1

Name: document-get-pages-reused
Description: {get a page, then get it again}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set p0a [$pdf getpage 0]
    set p0b [$pdf getpage 0]
    expr { $p0a eq $p0b }    
}
Cleanup: {
    $pdf quit
}
Expected: 1

Name: document-get-pages-and-quit-doc
Description: {open doc, get a page, quit doc}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set p2 [$pdf getpage 2]
    $pdf quit  ;# this should destroy doc and all the related pages
    mupdf::isobject $p2
}
Expected: 0

Name: document-get-pages-and-destroy-doc
Description: {open doc, get a page, destroy doc}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set p2 [$pdf getpage 2]
    rename $pdf {}  ;# this should destroy doc and all the related pages
    mupdf::isobject $p2
}
Expected: 0

Name: document-get-wrong-page-1
Description: {open doc, get page -1}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set page [$pdf getpage -1]
}
Cleanup: {
    $pdf quit
}
Expected: error "page number out of bound."

Name: document-get-wrong-page-max
Description: {open doc, get page n}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set n [$pdf npages]
    set page [$pdf getpage $n]
}
Cleanup: {
    $pdf quit
}
Expected: error "page number out of bound."

Name: page-type
Description: {open doc, get page and its type}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set page [$pdf getpage 3]
    list  [mupdf::isobject $page] [mupdf::classinfo $page]
}
Cleanup: {
    $pdf quit
}
Expected: {1 ::mupdf::Page}

Name: page-number
Description: {open doc, get page 4 and return page number}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set page [$pdf getpage 4]
    $page pagenumber
}
Cleanup: {
    $pdf quit
}
Expected: 4

Name: page-close
Description: {open doc, open a page, close the page}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set page [$pdf getpage 4]
    $page close
    list [mupdf::isobject $page] [$pdf openedpages]
}
Cleanup: {
    $pdf quit
}
Expected: {0 {}}

Name: closepage
Description: {open doc, open a page, close the page}
Setup: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
}
Test: {
    $pdf getpage 4
	$pdf getpage 2    
    
	$pdf closepage 4
    $pdf closepage 999  ;# it's not an error
    list  [$pdf openedpages]
}
Cleanup: {
    $pdf quit
}
Expected: {2}

Name: closepages
Description: {open doc, open 2 pages, close all the opened pages}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set page4 [$pdf getpage 3]
    set page0 [$pdf getpage 0]
    set pagesBefore [llength [$pdf openedpages]]
    $pdf closeallpages
    set pagesAfter [llength [$pdf openedpages]]
    list $pagesBefore $pagesAfter
}
Cleanup: {
    $pdf quit
}
Expected: {2 0}


Name: page-docref
Description: {from a page get its document}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set page [$pdf getpage 4]
    set pdfRef [$page docref]
    expr {$pdf eq $pdfRef}
}
Cleanup: { $pdf quit }
Expected: {1}


Name: saveImage
Description: {some commands are not availble with mupdf-notk}
Test: {
    set pdf [mupdf::open [file join $samplesDir Sample-01.pdf]]
    set page [$pdf getpage 0]    
    $page saveImage aTkImage
}
Cleanup: { $pdf quit }
Expected: error glob {unknown method "saveImage": *}


Name: fullname.1
Description: {get the full.name of an an opened PDF}
Setup: { 
    set filename  [file join $samplesDir Hello.pdf]
    set pdf [mupdf::open $filename]
}
Test: {
    expr {[$pdf fullname] == [file normalize $filename]}
}
Cleanup: { $pdf quit }
Expected: 1


Name: isopen
Description: {isopen: the first is opened, the second is not opened}
Setup: { 
    set filename  [file join $samplesDir Hello.pdf]
    set pdf [mupdf::open $filename]
}
Test: {
    list [mupdf::isopen $filename] [mupdf::isopen Other.pdf]
}
Cleanup: { $pdf quit }
Expected: {1 0}

Name: doc.version
Description: {get the doc's PDF version}
Setup: { 
    set filename  [file join $samplesDir Form-Sample-01.pdf]
    set pdf [mupdf::open $filename]
}
Test: {
    $pdf version
}
Cleanup: {$pdf quit}
Expected: "1.7"


 # FINAL TEST----------------------------------------------------------------
Name: memory-leaks
Description: { check if all created objects were properly destroyed }
Test: {
    set L {}
    lappend L [llength [mupdf::Doc  names]]
    lappend L [llength [mupdf::Page names]]
}    
Expected: {0 0}



# === cleanup ========================================
::tcltest::cleanupTests
