content: -- Copyright (C) 2012 Robin Trew
  --
  -- Permission is hereby granted, free of charge, 
  -- to any person obtaining a copy of this software 
  -- and associated documentation files (the "Software"), 
  -- to deal in the Software without restriction, 
  -- including without limitation the rights to use, copy, 
  -- modify, merge, publish, distribute, sublicense, 
  -- and/or sell copies of the Software, and to permit persons 
  -- to whom the Software is furnished to do so, 
  -- subject to the following conditions:
  
  -- *******
  -- The above copyright notice and this permission notice 
  -- shall be included in ALL copies 
  -- or substantial portions of the Software.
  -- *******
  
  -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
  -- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
  -- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
  -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
  -- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
  -- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  property pTitle : "Expand FT doc to level N"
  property pVer : "0.08"
  property pAuthor : "Rob Trew, www.complexpoint.net"
  
  -- Ver 0.05 doesn't add leaf nodes to the collapsed list
  
  -- WORKS WITH LAUNCHBAR,
  -- give an absolute expansion level, or an adjustment like +1 -2 etc 
  -- (a simple + or - is interepreted as +1 or -1)
  
  property plngDialog : 0
  property plngOneMore : 1
  property plngOneLess : 2
  property plngBehaviour : plngOneMore
  
  on handle_string(strLevel)
  	tell application "FoldingText"
  		set lstDocs to documents
  		if length of lstDocs < 1 then return
  		set oDoc to item 1 of lstDocs
  		set lngMax to (my MaxDepth(oDoc)) + 1
  		my ShowLevel(strLevel, oDoc, lngMax)
  	end tell
  end handle_string
  
  -- OR WITHOUT LAUNCHBAR ...
  on run
  	if plngBehaviour = plngDialog then
  		tell application "FoldingText"
  			set lstDocs to documents
  			if length of lstDocs < 1 then return
  			set oDoc to item 1 of lstDocs
  			
  			set lngMax to (my MaxDepth(oDoc)) + 1
  			
  			activate
  			try
  				set varLevel to (display dialog "Expand to level (1-" & lngMax & ")" & return & return & ¬
  					"(or amount to adjust expansion by: +1 -2 etc)." default answer lngMax buttons {"Cancel", "OK"} ¬
  					cancel button "Cancel" default button "OK" with title pTitle & "  ver. " & pVer)
  			on error
  				return
  			end try
  			set varLevel to text returned of varLevel
  			my ShowLevel(varLevel, oDoc, lngMax)
  		end tell
  	else if plngBehaviour = plngOneMore then
  		handle_string("+1")
  	else -- one less
  		handle_string("-1")
  	end if
  end run
  
  -- WHAT IS THE DEEPEST LEVEL OF NESTING
  on MaxDepth(oDoc)
  	set strLevel to "/*"
  	tell application "FoldingText"
  		set strPath to strLevel
  		set lngLevel to -1
  		tell front document
  			set lngNodes to length of (read text it at path strPath)
  			repeat while lngNodes > 0
  				set lngLevel to lngLevel + 1
  				set strPath to strPath & strLevel
  				set lngNodes to length of (read text it at path strPath)
  			end repeat
  		end tell
  	end tell
  	return lngLevel
  end MaxDepth
  
  -- What is the level of the most senior node which is currently collapsed ?
  on GetLevel(oDoc, lngMax)
  	tell application "FoldingText"
  		set lngMin to lngMax
  		set lstCollapsed to read collapsed nodes oDoc
  		if length of lstCollapsed = 0 then return lngMax
  		repeat with oRec in lstCollapsed
  			if |type| of oRec is not "empty" then
  				set lngLevel to (length of (read nodes oDoc at path "///@id=" & (|id| of oRec)))
  				if lngLevel < lngMin then set lngMin to lngLevel
  			end if
  		end repeat
  		return lngMin
  	end tell
  end GetLevel
  
  -- Set an absolute expansion level, or adjust the expansion level by a delta
  on ShowLevel(strLevel, oDoc, lngMax)
  	tell application "FoldingText"
  		set blnPlus to strLevel contains "+"
  		set blnMinus to strLevel contains "-"
  		set blnDelta to (blnPlus or blnMinus)
  		try
  			set lngValue to strLevel as integer
  		on error
  			if not blnDelta then
  				activate
  				display dialog strLevel & " could not be interpreted as a level or adjustment" buttons {"OK"} default button "OK" with title pTitle & "  ver. " & pVer
  				return
  			else
  				if blnMinus then
  					set lngValue to -1
  				else
  					set lngValue to 1
  				end if
  			end if
  		end try
  		
  		if blnDelta then
  			set lngLevel to (my GetLevel(oDoc, lngMax)) + lngValue
  		else
  			set lngLevel to lngValue
  		end if
  		if lngLevel > lngMax then set lngLevel to lngMax
  		if lngLevel > 0 then
  			-- EXPAND THE NODES ABOVE THE TARGET LEVEL
  			lngLevel
  			set lstNodes to my NodesWhereLevel(oDoc, lngLevel, true)
  			update collapsed nodes oDoc with changes {|removeNodes|:lstNodes}
  			
  			-- AND COLLAPSE THE TARGET LEVEL ITSELF
  			set lstNodes to my NodesWhereLevel(oDoc, lngLevel, false)
  			update collapsed nodes oDoc with changes {|addNodes|:lstNodes}
  		else
  			-- EXPAND COMPLETELY
  			set lstNodes to read nodes oDoc at path "/*"
  			update collapsed nodes oDoc with changes {|addNodes|:lstNodes}
  		end if
  		
  	end tell
  end ShowLevel
  
  -- Return parent nodes at a specific level
  -- or all nodes parental to that level
  on NodesWhereLevel(oDoc, lngLevel, blnAbove)
  	set strChiln to "/*"
  	set strLevel to ""
  	if blnAbove then
  		set lngClear to lngLevel - 1
  		if lngClear < 1 then
  			return {}
  		else
  			repeat with i from 1 to (lngLevel - 1)
  				set strLevel to strLevel & strChiln
  			end repeat
  			set strLevel to strLevel & "/ancestor-or-self::*"
  		end if
  	else
  		-- Get *parents* at the given level
  		-- (we don't want to add leaves to the collapsed list)
  		repeat with i from 1 to (lngLevel + 1)
  			set strLevel to strLevel & strChiln
  		end repeat
  		set strLevel to strLevel & "/parent::*"
  	end if
  	
  	tell application "FoldingText" to return (read nodes oDoc at path strLevel)
  end NodesWhereLevel
  
  
  
  