
class comancheView {
    variable pw
    constructor { frame guiBuilder} {
        set _guiBuilder $guiBuilder
	set pw [PanedWindow $frame.pw -side bottom]
	$pw add -weight 1 -minsize 30
	$pw add -weight 1 -minsize 30
	pack $pw -fill both -expand true
        set _treeView [comancheTree #auto [$pw getframe 0]  $this]
        set _rightPane [rightPane #auto [$pw getframe 1] $this]
	set _guiBuilder $guiBuilder
	set _ppDialog [propertyPagesDialog ::#auto $guiBuilder]
	set _wizardDialog [comanche::wizardDialog ::#auto $guiBuilder]
    } {}

    method newNamespace { namespace }
    method populateRequestNotify { node }
    method nodeSelectedNotify { node }
    method showMenuRequest { node}
    method _addNode { parentNode node args}
    method _removeNode { node }
    method _configureNode { view node namespace xuiNode }
    method deleteNodeRequest { node }
    method processSignal { signal args}
    method processURL { url }
    method showPropertyPages { nodeId }
    method showPropertyPagesDialog { nodeId docInfo propertyPagesList}
    method submitPropertyPagesResponse { nodeId docInfo xuiPP}
    method copyNode {}
    method pasteNode
    method showWizard {type node}
    method showWizardPage {node docInfo propertyPagesList}
    method submitWizardResponse { nodeId docInfo propertyPageList } 
    method showCommand {node docInfo}
    method refreshRightPane
    method nodesChanged { args }    
    method _buildMenu {menuDescription menu}    
    # namespace we are associated with (in this case namespace == tree + processing of xuiDocuments)
    variable _namespace
    variable _treeView
    variable _rightPane
    variable _callerId    
    variable _guiBuilder
    variable _ppDialog
    variable _wizardDialog
}

body comancheView::nodesChanged {args} {
    array set opts $args
    foreach event $opts(-eventList) {
        array set info $event
	array set nodeInfo $info(-node)    
	switch $info(-change) {
	   added {
	       eval _addNode $nodeInfo(-parent) $nodeInfo(-nodeId) $info(-node)
	   } deleted {
	      _removeNode $nodeInfo(-nodeId)
	   } modified {
	   }
	}
    }   
   
}

body comancheView::refreshRightPane {} {

    # By default, will select current node

    processSignal selectNode 
}

body comancheView::processURL {url} {
    if [winfo exists .d ] {
	return
    }
    withBusyCursor {
	array set options [comanche::html::decodeURL $url]
	switch $options(_action) {
	    documentRequest {
		switch $options(_documentType) {
		    propertyPages {
			array set ppOptions {_skillLevel basic _documentSubtype {}}
			array set ppOptions [array get options]
			showPropertyPages $ppOptions(_node)
		    } wizard {
			array set wizardOptions {_skillLevel basic _documentSubtype {}}
			array set wizardOptions [array get options]
			showWizard $wizardOptions(_documentSubtype) $wizardOptions(_node)
		    } command {
			set docInfo [list \
				skillLevel basic \
				documentType command \
				documentSubtype $options(_documentSubtype) \
				overwrite 0]
			showCommand $options(_node) $docInfo
		    } default {
			error "Unknown document type $options(_documentType)
		    }
		}
	    } selectNode {
		if [catch {$_treeView selectNode $options(_node)}] {
		    
		    # Hack for remove plugin
		    
		    $_treeView selectNode nodeid1
		}
	    } deleteNodeRequest {
		deleteNodeRequest $options(_node)
	    }
	}
    }
}

body comancheView::processSignal {signal args} {
    array set options {	-node {} }
    array set options $args
    set node $options(-node)
    switch $signal {
	copyNode {
	} levelUp {
	    catch " \
	    $_treeView selectNode \
	    [$_treeView getParentNode $node] "
	} selectViewNode {
	} propertyPages {
	    showPropertyPages $node
	} addNewNode {
	    showWizard add $node
	} selectNode {
	    
	    # For example, when restoring back up
	    
	    if [catch {$_treeView selectNode $node}] {
		$_treeView selectNode nodeid1
	    }
	} default {
	   # All the other not known commands will be send as-is to the plugIn
	   showCommand $node $signal
	}
    }
}

body comancheView::showMenuRequest { nodeId } {
    set menuDescription [$_namespace documentRequest $nodeId \
	    [list documentType menu skillLevel basic] $_callerId]
    if [string length $menuDescription] {
	set menu [menu .[unique::newId] -tearoff 0]
	_buildMenu $menuDescription $menu
	tk_popup $menu [winfo pointerx .] [winfo pointery .]
    }
}

body comancheView::_buildMenu {menuDescription menu} {
   foreach menuEntry $menuDescription {
      array set properties {-state normal}
      array set properties $menuEntry
      switch $properties(-type) {
	 command {
    	    $menu add command -label $properties(-label) \
  	      -command "$this processURL $properties(-command)" \
	      -state $properties(-state)
	 } separator {
    	    $menu add separator      
	 } cascade {
	    set cascademenu [menu $menu.[unique::newId] -tearoff 0]
	    _buildMenu $properties(-childmenu) $cascademenu
	    $menu add cascade -label $properties(-label) -menu $cascademenu 
	 }
      } 
   }
}

body comancheView::deleteNodeRequest {nodeId} {
    $_namespace deleteNodeRequest $nodeId $_callerId
}

# We want to refactor this into a single call, as showPropertyPages and showWizard are so similar
# Property pages could be a type of wizard


body comancheView::showPropertyPages { nodeId } {
    set answer [$_namespace documentRequest $nodeId \
	    [list documentType propertyPages overwrite 0 skillLevel basic] $_callerId]
    set docInfo [lindex $answer 0]
    set xuiPP [xuiStructure ::#auto]
    $xuiPP setXuiClass propertyPages
    $xuiPP setName propertyPages  
    foreach pp [lindex $answer 1] {
        $xuiPP addComponent $pp
    }
    showPropertyPagesDialog $nodeId $docInfo $xuiPP
}

body comancheView::showPropertyPagesDialog { nodeId docInfo xuiPP } {
    array set documentInfo $docInfo
    switch [$_ppDialog show $xuiPP] {
	OK {
	    submitPropertyPagesResponse $nodeId [array get documentInfo] [$xuiPP getComponents]
	} 
	CANCEL {
	}
    }
}

body comancheView::submitPropertyPagesResponse { nodeId docInfo xuiPP } {
    set response [$_namespace documentResponse $nodeId \
	    $docInfo $xuiPP $_callerId]
    set code [lindex $response 0]
    set data [lindex $response 1]
    switch -- $code {
	ok {
	    processSignal selectNode -node $nodeId
	    return
	} info {
	    MessageDlg .d -message $data -type ok -icon info
	    processSignal selectNode -node $nodeId
	    return
	} error {
	    MessageDlg .d -message $data -type ok -icon error
	    showPropertyPagesDialog $nodeId $docInfo $xuiPP
	} warningyesno {
	    switch [MessageDlg .d -message $data  -type okcancel -icon warning] {
		0 {
		    # OK: Resubmit with overwrite flag
		    array set documentInfo $docInfo
		    set documentInfo(overwrite) 1
		    submitPropertyPagesResponse \
			    $nodeId [array get documentInfo] [$xuiPP getComponents]
		    return
		}
		1 {
		    showPropertyPagesDialog $nodeId $docInfo $xuiPP    
		}
	    }
	} default {
	    error "Could not understand response $code $data"
	}
    }
    processSignal selectNode -node $nodeId
}

body comancheView::showWizard { type nodeId } {
    if ![string compare $nodeId root] { return }
    set answer [$_namespace documentRequest $nodeId \
	    [list documentType wizard documentSubtype $type skillLevel basic] \
	    $_callerId]
    set docInfo [lindex $answer 0]
    set propertyPageList [lindex $answer 1]
    showWizardPage $nodeId $docInfo $propertyPageList
}

body comancheView::showWizardPage { nodeId docInfo propertyPageList } {
    array set documentInfo $docInfo
    set selectedPageName $documentInfo(selectedPageName)
    if ![string length $selectedPageName] {
	error "Please select a page"
    }
    set event [string tolower [$_wizardDialog show $selectedPageName $propertyPageList]]
    switch $event {
	next - prev {
	    set documentInfo(pageEvent) $event
	    set documentInfo(documentType) wizard
	    submitWizardResponse $nodeId [array get documentInfo] $propertyPageList
	} cancel {
	}
    }
}

body comancheView::submitWizardResponse { nodeId docInfo propertyPageList } {
    set response [$_namespace documentResponse $nodeId \
	    $docInfo $propertyPageList $_callerId]
    set code [lindex $response 0]
    set data [lindex $response 1]
    switch -- $code {
	ok {
	    if ![string length $data] {
		# If no more data, we are done
		return
	    }
	    set docInfo [lindex $data 0]
	    set propertyPageList [lindex $data 1]
	    showWizardPage $nodeId $docInfo $propertyPageList
	    processSignal selectNode -node $nodeId
	    return
	} info {
	    MessageDlg .d -message $data -type ok -icon info
	    processSignal selectNode -node $nodeId
	    return
	} error {
	    MessageDlg .d -message $data -type ok -icon error
	    showWizardPage $nodeId $docInfo $propertyPageList
	} warningyesno {
	    switch [MessageDlg .d -message $data  -type okcancel -icon warning] {
		0 {
		    # OK: Resubmit with overwrite flag
		    array set documentInfo $docInfo
		    set documentInfo(overwrite) 1
		    submitWizardResponse $nodeId [array get documentInfo] $propertyPageList
		    return
		}
		1 {
		    showWizardPage $nodeId $docInfo $propertyPageList    
		}
	    }
	} default {
	    error "Could not understand response $code $data"
	}
    }
    processSignal selectNode -node $nodeId
}

body comancheView::showCommand {nodeId documentInfo} {
    set response [$_namespace documentResponse \
	    $nodeId $documentInfo {} $_callerId]
    set code [lindex $response 0]
    set data [lindex $response 1]
    switch -- $code {
	ok {
	    if ![string length $data] {
		set data "Command executed ok"
	    }
	    MessageDlg .d -message $data -type ok -icon info
	    return
	} error {
	    MessageDlg .d -message $data -type ok -icon error
	} warningyesno {
	    switch [MessageDlg .d -message $data  -type okcancel -icon warning] {
		0 {
		    # OK: Resubmit with overwrite flag
		    array set documentInfo $docInfo
		    set documentInfo(overwrite) 1
		    showCommand $nodeId [array get documentInfo] {}
		    return
		}
		1 {
		    return
		}
	    }
	} default {
	    error "Could not understand response $code $data"
	}
    }
}

body comancheView::copyNode { } {
    foreach {clipboardNamespace  clipboardNode} \
	    $View2NsArray([list $currentView [$currentView getSelectedNode]])\
	    break
}

body comancheView::pasteNode { } {
}


body comancheView::populateRequestNotify { parentNode } {
   foreach firstLevelChild [$_namespace nodeCget $parentNode {-children} $_callerId] {
      set attrs [$_namespace nodeCget $firstLevelChild {} $_callerId]
      eval $this _addNode $parentNode $firstLevelChild $attrs
   }
}

body comancheView::nodeSelectedNotify { nodeId } {
    set doc [$_namespace documentRequest $nodeId \
	    {documentType rightPaneContent skillLevel basic} $_callerId] 
    $_rightPane loadHTML $doc
}

body comancheView::_addNode { parentNode node args}  {
    set type leaf
    array set opts $args
    if [::comanche::doYouBelongTo container $opts(-classList)] {
           set type container
    }
    $_treeView addNode $parentNode $node \
	    -openImage $opts(-openImage) \
	    -closedImage $opts(-closedImage) \
	    -text $opts(-text) \
	    -type $type 
}

body comancheView::_removeNode {node}  {
    $_treeView deleteNode $node
}

body comancheView::newNamespace { namespace } {
    # Take all first level children 
    set _namespace $namespace
    set _callerId [$namespace registerConsole $this]
    populateRequestNotify root

    # XXX This is a hac to make it look pretty the first time

    foreach node {nodeid1 nodeid2 nodeid3} {
	catch {$_treeView _openNode $node}
    }
    if [catch {processSignal selectNode -node nodeid3}] {
	processSignal selectNode -node nodeid1
    }

   
}

body comancheView::_configureNode { view node namespace xuiNode }  {
    $view configureNode $node -openImage [$xuiNode getOpenIcon]\
	    -closedImage [$xuiNode getClosedIcon]\
	    -text [$xuiNode getLabel ] \
	    -type container 
}
