# -*- coding: iso-8859-1 -*-
"""
	MoinMoin - Freemind sitemap Flash Browser macro (for MoinMoin V1.8.x)

	Thin macro based on FreeMind Browser (applet) macro and
	FreemindFlashBrowser macro.

	Creates a sitemap of your wiki in the freemind format and inserts the
	FreeMind Flash Browser.
	
	See http://freemind.sourceforge.net/wiki/index.php/Flash

	<<FreeMindFlashBrowser()>>
		displays the sitemap in the FreeMind browser applet with  the
		default for the width, height, and collapsedToLevel of the applet.

	<<FreeMindFlashBrowser( width )>>
		displays the FreeMind mindmap specified by urlOfMindmap in the FreeMind
		browser applet the width is taken from the argument list there is a
		default for the height and collapsedToLevel of the applet.

	<<FreeMindFlashBrowser( width, height )>>
		displays the FreeMind mindmap specified by urlOfMindmap in the FreeMind
		browser applet the width and height are taken from the argument list.
		There is a default for the collapsedToLevel of the applet.

	<<FreeMindFlashBrowser( width, height, collapsedToLevel )>>
		displays the FreeMind mindmap specified by urlOfMindmap in the FreeMind
		browser applet the width, height and collapsedToLevel are taken from the
		argument list.

	@copyright: 2007 by Bum-seok Lee <shinsuk@gwbs.net>
	            2009 by Josef Meier <jo.meier@gmx.de>
	@license: GNU GPL, see COPYING for details.
"""

"""
	Changes:

		2007-12-14 siemster <gregory.siems@pca.state.mn.us>
			- Moved mmcachedir to wikiconfig ( as freemind_cache_dir )
			- Moved mmmcacheurl to wikiconfig ( as freemind_cache_url )
			- Moved flashurl to wikiconfig  ( as freemind_flash_browser_url )
			- Added CSSFile ( freemind_css_url in wikiconfig )
			- Added collapsedToLevel
			- Changed 'div id' of the applet script to a generated value
				(for the purpose of allowing multiple instances within the
				same wiki page)

		2008-06-27 siemster <gregory.siems@pca.state.mn.us>
			- Fix to work with Moin version 1.7
			
		2009-09-10 Added code for automatic creation of freemind data
		           out of your wikis structure. 

"""

from MoinMoin import config, wikiutil, action
from MoinMoin.action import AttachFile
import os
import md5
import time
import codecs

debug = False

# FMBMacro class

"""
	Class FMBMacro implements the execution of a FreeMindFlashBrowser macro call.
	One instance must be used per execution.
"""
class FMBMacro:

	widthDefault = '100%'
	heightDefault= '500'
	collapsedLevelDefault = '2'

	"""
		Construct the FMBMacro with the execution arguments.
	"""
	def __init__(self, macro, args):
		self.macro = macro
		self.args = args
		self.request = macro.request

		self.flashBaseUrl  = macro.request.cfg.freemind_flash_browser_url
		self.cssUrl        = macro.request.cfg.freemind_css_url
		self.mmCacheUrl    = macro.request.cfg.freemind_cache_url
		self.mmCacheDir    = macro.request.cfg.freemind_cache_dir

		# Check and set, if we have an HTML formatter
		self.isHTML = '<br />\n' == self.macro.formatter.linebreak(0)

		# Fix for Moin 1.7.x
		if not self.isHTML:
			self.isHTML = '<br>\n' == self.macro.formatter.linebreak(0)

		self.isFatal = False
		self.applet = [] # this is for the applet code
		self.messages = [] # this is for extra messages


	def execute( self ):
		self.info( "Yippieh - FMBMacro is executing!" )
		self.getFreemindSitemap()
		self.checkArguments()
		self.computeResult()
		return self.result


	"""
		Get sitemap in freemind format by using the "FreemindSitemap" action.
	"""
	def getFreemindSitemap(self):
		freemindSitemap = action.getHandler(self.request, 'FreemindSitemap', 'getSiteMapFreemind')
		
		if freemindSitemap:
			freemindContent = freemindSitemap(self.request.page.page_name, self.request)
		
		if not os.path.isdir(self.mmCacheDir):
			os.mkdir(self.mmCacheDir, 0755)

		hashStart = time.asctime(time.gmtime()) + self.request.user.id	

		filename = md5.new(hashStart).hexdigest() + ".mm"
		completeName = os.path.join ( self.mmCacheDir, filename )

		filehandle = open(completeName,"w")
		filehandle.write( freemindContent.encode( "utf-8" ) )
		filehandle.close()
		self.mindmapUrl = self.mmCacheUrl + "/" + filename


	"""
		Check the arguments given with the macro call.
	"""
	def checkArguments(self):
		if not self.args:
			argsList = []
			argsLen = 0
		else:
			argsList = self.args.split(',')
			argsLen = len(argsList)

		self.width = FMBMacro.widthDefault
		self.height = FMBMacro.heightDefault
		self.collapsedLevel = FMBMacro.collapsedLevelDefault

		if 1 <= argsLen:
			temp = argsList[0].strip()
			if temp != '':
				self.width = temp

		if 2 <= argsLen:
			temp = argsList[1].strip()
			if temp != '':
				self.height = temp

		if 3 <= argsLen:
			temp = argsList[2].strip()
			if temp != '':
				self.collapsedLevel = temp

		if 3 < argsLen:
			self.warning( "Too many arguments!" )
			self.usage()

		if True:
			self.info( "isHTML= '%s'" %(self.isHTML) )
			self.info( "width= '%s'" %(self.width) )
			self.info( "height= '%s'" %(self.height) )
			self.info( "startCollapsedToLevel= '%s'" %(self.collapsedLevel) )
			self.info( "mindmap-url= '%s'" %(self.mindmapUrl) )
			self.info( "isFatal= '%s'" %(self.isFatal) )
			self.usage()

	"""
		Compute the result of the macro call.
	"""
	def computeResult(self):
		result = "".join( self.messages )

		if not self.isFatal:
			self.computeApplet()
			result += "".join( self.applet )

		if self.isHTML:
			self.result = self.macro.formatter.rawHTML( result )
		else:
			self.result = result


	"""
		Compute the applet link or applet tag (depending on formatter)
	"""
	def computeApplet( self ):
		if self.isHTML:
			divId = md5.new(self.mindmapUrl).hexdigest()

			applet = """
<!--
 - code generated by FreeMindFlashBrowser flash macro -
 - see http://freemind.sourceforge.net -
-->
<script type="text/javascript" src="%s/flashobject.js"></script>

<div id="%s">
	FreemindSitemap isn't working. Maybe you forgot to configure it in 'wikiconfig.py'.
	Or maybe your browsers Flash plugin or Javascript are turned off.
	Activate both and reload to view the mindmap
</div>

<script type="text/javascript">
	// <![CDATA[
	var fo = new FlashObject("%s/visorFreemind.swf", "visorFreeMind", "%s", "%s", 6, "#9999ff");
	fo.addVariable("openUrl", "_self");
	fo.addVariable("initLoadFile", "%s");
	fo.addVariable("startCollapsedToLevel", "%s");
	fo.addVariable("CSSFile", "%s");
	fo.write("%s");
	// ]]>
</script>
""" %( self.flashBaseUrl, divId, self.flashBaseUrl, self.width, self.height,
			self.mindmapUrl, self.collapsedLevel, self.cssUrl, divId, )
			self.applet.append( applet )

		else:
			self.applet.append( self.macro.formatter.url( 1, self.mindmapUrl ) )
			self.applet.append( self.macro.formatter.url( 0 ) )


	# message methods

	def info( self, msg ):
		if debug:
		    self.msg( 'Info: ' + msg )

	def warning( self, msg ):
		self.msg( 'Warning: ' + msg )

	def error( self, msg ):
		self.msg( 'Error: ' + msg )

	def fatal( self, msg ):
		self.msg( 'Fatal: ' + msg )
		self.isFatal = True

	def msg( self, msg ):
		msg = "FreemindSitemap-Macro:" + msg
		print msg
		if self.isHTML:
			msg = '<h1 style="font-weight:bold;color:blue">' + msg.replace( '\n', '\n<br/>') + '</h1>'

		self.messages.append(msg)


	def usage( self ):
		usage = """
		Usage: <<FreemindSitemap( [,urlOfMindmap [,width [,height]] )]]
			urlOfMindmap: an URL reaching the mindmap - allowed schemes are 'http:' and 'attachment:'.
			width:		      (optional) - width of the applet; default: %s
			height:		      (optional) - height of the applet; default: %s
			startCollapsedToLevel (optional) - start collapsed to to node level; default: %s
		""" %(self.widthDefault, self.heightDefault, self.collapsedLevelDefault)

		self.info( usage )


	"""
		Take the given URL of the mindmap, validate it and return an URL that can be linked to from the applet.
	"""
	def getMindmapURL( self, url ):

		if url.startswith( 'http:' ):
			return url

		elif url.startswith( 'attachment:'):
			mmFileName = url[11:]
			pagename, drawing = AttachFile.absoluteName(url, self.request.page.page_name)
			mindmap_url = AttachFile.getAttachUrl(pagename, mmFileName, self.request)
			return mindmap_url

		else:
			self.warning( "Unrecognized scheme in mindmap URL! Url is '%s'!" %(url) )
			self.usage()
			return url


# Macro execution interface

def execute(macro, args):
        fmb = FMBMacro( macro, args )
        return fmb.execute()

# vim: ai si cin noet ts=4 sw=4

