#
# copyright_notice
#

import sys, string
#from mglutil.regression import testplus

from NetworkEditor.net import Network
from NetworkEditor.simpleNE import NetworkNode
from time import sleep

ed = None
node1 = None
node2 = None
withThreads = 0 # default is: multi-threading off

# allow for additional user input
if len(sys.argv):
    for myArg in sys.argv[1:]:
        if myArg[:11] == 'withThreads':
            withThreads = int(string.strip(myArg)[-1])


def setUp():
    from NetworkEditor.simpleNE import NetworkBuilder
    global ed
    ed = NetworkBuilder("test builder1", withShell=0,
                        visibleWidth=400, visibleHeight=300)
    ed.master.update()
    ed.configure(withThreads=withThreads)


def tearDown():
     ed.exit_cb()
    #ed.master.after(1000, ed.exit_cb )


def pause(sleepTime=0.4):
    ed.master.update()
    sleep(sleepTime)


def test_configure():
    dict = ed.configure()
    assert len(dict.items()) > 0
    
    assert 'withThreads' in dict.keys()
    ed.configure(withThreads=0)
    assert ed.withThreadsTk.get() == 0
    ed.configure(withThreads=1)
    assert ed.withThreadsTk.get() == 1
    ed.configure(withThreads=withThreads) # set it back to user specified val
    assert ed.withThreadsTk.get() == withThreads

    assert 'restoreWidgetValue' in dict.keys()
    oldval = ed.restoreWidgetValueTk.get()
    ed.configure(restoreWidgetValue=0)
    assert ed.restoreWidgetValueTk.get() == 0
    ed.configure(restoreWidgetValue=1)
    assert ed.restoreWidgetValueTk.get() == 1
    ed.configure(restoreWidgetValue=oldval) # set it back to user specified val
    assert ed.restoreWidgetValueTk.get() == oldval
    
    assert 'colorNodeByLibrary' in dict.keys()
    oldval = ed.colorNodeByLibraryTk.get()
    ed.configure(colorNodeByLibrary=0)
    assert ed.colorNodeByLibraryTk.get() == 0
    ed.configure(colorNodeByLibrary=1)
    assert ed.colorNodeByLibraryTk.get() == 1
    ed.configure(colorNodeByLibrary=oldval) # set it back to user specified val
    assert ed.colorNodeByLibraryTk.get() == oldval

    assert 'flashNodesWhenRun' in dict.keys()
    oldval = ed.flashNodesWhenRunTk.get()
    ed.configure(flashNodesWhenRun=0)
    assert ed.flashNodesWhenRunTk.get() == 0
    ed.configure(flashNodesWhenRun=1)
    assert ed.flashNodesWhenRunTk.get() == 1
    ed.configure(flashNodesWhenRun=oldval) # set it back to user specified val
    assert ed.flashNodesWhenRunTk.get() == oldval


def test_addDeleteNetwork():
    net = Network('test network')
    ed.addNetwork(net)
    ed.setNetwork(net)
    from ViPEr.StandardNodes import DialNE, Print
    node1 = DialNE()
    net.addNode(node1, 50, 50)
    node2 = Print()
    net.addNode(node2, 50, 100)
    net.connectNodes(node1, node2, 0, 0)
    ed.deleteNetwork(net)

    
def test_refreshNetwork():
    net = Network('test network')
    ed.addNetwork(net)
    ed.setNetwork(net)
    from ViPEr.StandardNodes import DialNE, Print
    node1 = DialNE()
    net.addNode(node1, 50, 50)
    node2 = Print()
    net.addNode(node2, 50, 100)
    net.connectNodes(node1, node2, 0, 0)

    # measure length on menu
    # asking the an index larger than the length of the menu returns the last
    # valide index
    length = node1.menu.index(1000)
    ed.refreshNet_cb()

    # make sure menu length has not changed
    assert node1.menu.index(1000) == length

    ed.deleteNetwork(net)
    


def test_addNode():
    global node1
    node1 = NetworkNode(name='node1')
    ed.currentNetwork.addNode(node1, 50, 50)
    assert len(ed.currentNetwork.rootNodes)==1
    pause()
    
    node1.rename('operator1')
    node1.select()
    pause()
    
    node1.deselect()
    pause()


def test_addPorts():
    # all default values
    p = node1.addInputPort()
    p = node1.addInputPort(name='secondPort', balloon='Hello there',
                           required=False, datatype='int')
    p = node1.addOutputPort()
    p = node1.addOutputPort(name='Noname', datatype='None')
    

def test_addConnection():
    global node1, node2
    node2 = NetworkNode(name='node2')
    ed.currentNetwork.addNode(node2, 50, 150)
    p = node2.addInputPort()
    assert len(ed.currentNetwork.rootNodes)==2
    pause()
    
    conn1 = ed.currentNetwork.connectNodes(node1, node2, 0, 0)
    assert len(ed.currentNetwork.rootNodes)==1
    assert node2.isRootNode==0
    assert node1.isRootNode==1
    pause()
    
    conn1.highlight()
    pause()
    
    conn1.unhighlight()
    pause()

    ed.currentNetwork.selectNodes([node1])
    pause()

    ed.currentNetwork.selectNodes([node2])
    pause()

    ed.currentNetwork.clearSelection()
    pause()
    
    node3 = NetworkNode(name='node3')
    ed.currentNetwork.addNode(node3, 110, 150)
    p = node3.addInputPort()
    conn2 = ed.currentNetwork.connectNodes(node1, node3, 1, 0,
                                           mode='straight')
    pause()

    node4 = NetworkNode(name='node4')
    ed.currentNetwork.addNode(node4, 170, 120)
    p = node4.addInputPort()
    conn3 = ed.currentNetwork.connectNodes(node1, node4, 1, 0,
                                           mode='angles', smooth=1)
    pause()

    # move the sub-network made of the selected nodes
    ed.currentNetwork.selectNodes([node1,node4])
    canvas = ed.currentNetwork.canvas

    # find out connections with 2, 1 and no node selected
    net = ed.currentNetwork
    co2, co1, no1 = net.getConnections(net.selectedNodes)
    halfSelConn = co1 # connections with only 1 node selected
    print co1
    for i in range(30):
        # selected nodes and connections between them have a tag 'selected'
        canvas.move('selected', 2, 0)
        # we need to update the connection between selected nodes and
        # unselected ones
        for c in halfSelConn:
            c.updatePosition()

        canvas.update()


def test_showHideGUI():
    ed.hideGUI()
    pause()

    ed.showGUI()
    pause()
    

def test_selectNodes():
    nodes=ed.currentNetwork.nodes
    for n in nodes:
        ed.currentNetwork.selectNodes([n])
    assert len(nodes) == len(ed.currentNetwork.selectedNodes)
    pause()


def test_deselectNodes():
    nodes=ed.currentNetwork.nodes
    for n in nodes:
        ed.currentNetwork.deselectNodes([n])
    assert len(ed.currentNetwork.selectedNodes) == 0
    pause()


def test_deleteConnection():
    ed.currentNetwork.deleteConnections([ed.currentNetwork.connections[0]])
    assert len(ed.currentNetwork.connections) == 2
    pause()


def test_deleteNodes():
    nodes=ed.currentNetwork.nodes
    for n in nodes:
        ed.currentNetwork.selectNodes([n])
    ed.currentNetwork.deleteNodes(ed.currentNetwork.selectedNodes)
    assert len(ed.currentNetwork.nodes) == 0
    pause()
    

def test_addCodeToNode():
    # set code of node to output 42, then run node and check if this worked
    global node1
    node1 = NetworkNode(name='Test Code')
    ed.currentNetwork.addNode(node1, 50, 50)
    p = node1.addOutputPort(name='output')
    # set code
    node1.setFunction("def doit(self):\n  i=0\n  i=i+42\n"+\
                      "  self.outputData(output=i)\n")

    # run network
    ed.currentNetwork.run()
    node1.network.waitForCompletion()
    
    # test that node has run the code and output 42
    assert node1.outputPorts[0].data == 42
    pause()

    
## harness = testplus.TestHarness( __name__,
##                                 connect = startEditor,
##                                 funs = testplus.testcollect( globals()),
##                                 disconnect = quitEditor
##                                 )

if __name__ == '__main__':
    print harness
    sys.exit( len( harness))
