# -*- coding: iso-8859-1 -*-
"""
MoinMoin - State macro
This macro create an clickable icon on the page content.
On clicking the image, an menu opens.
By selecting an other icon at the menu, the clicked image would be changed.

@copyright: 2007 by Richard Flieger
@license: GNU GPL, see COPYING for details.
    
----

Purpose:

 This macro is used to create todo-lists.

Functions:

 * no identifier needet
 * I18N support
 * 2-klick editing

Usage:

 [[State]]                 -> without arguments
 [[State()]]               -> with empty arguments
 [[State(  )]]             -> with spaces as arguments
 [[State( UnknownState )]] -> with wrong state

 [[State(TODO)]]           -> upper case
 [[State( TODO   )]]       -> upper case and spaces
 [[State(todo)]]           -> lower case 
 [[State( todo   )]]       -> lower case and spaces
 
Examples:

All states are open/todo, without arguments
---->8--------------------------

 [[State]] buy apples
 
 [[State]] looking for a present
 
 [[State]] write a letter
 
----8<-------------------------

A little game
---->8--------------------------
= Connect Four =

 (./) Player 1

 {X} Player 2

  || [[State]] || [[State]] || [[State]] || [[State]] ||
  || [[State]] || [[State]] || [[State]] || [[State]] ||
  || [[State]] || [[State]] || [[State]] || [[State]] ||
  || [[State]] || [[State]] || [[State]] || [[State]] ||

Modification history:

2007-06-25: first release

"""

from MoinMoin import config
from MoinMoin.Page import Page
import re

# the statelist has to be the same as the statelist of the macro
statelist = {"todo" : "/!\\",
             "done" : "(./)",
             "aborted" : "{X}",
             "inprogress" : "(!)",
             "fun" : ":)"}

Defaultstate = "todo"

Dependencies = ["pages", "user"]

class State:
    
    Dependencies = Dependencies

    def __init__(self, macro, args):
        self.macro = macro
        self.request = macro.request
        self.formatter = macro.formatter
        self.state = args
        
    def getArgs(self, string):
        if not string:
            return ["", ""]
        args = [s.strip() for s in string.split( ',' )]
        return args

    def renderInPage(self):
        fmt = self.formatter
        state = str( self.state )
        self.pagename = self.request.page.page_name
        state = validState( state )
        smileycode = getSmileyCode( state )
        smileys = config.smileys.items()
        iconimg = ""
        for s in smileys:
            if smileycode == s[0]:
                iconimg = fmt.smiley( smileycode )
                break
        smileys.sort()
        rev = self.getReversion()
        id = self.getID()
        html = u""
        permission = self.request.user.may.write( self.pagename )
        if permission:
            html += getHTML( state, iconimg, id, rev)
        else:
            html += iconimg
        return u''.join(html)
    
    def setID( self, id ):
        self.request.stateID = id
        
    def getID(self):
        try:
            macroid = self.request.stateID
        except:
            macroid = 1
        self.setID( macroid + 1 )
        return macroid
    
    def getReversion(self):
        page = Page( self.request, self.pagename )
        rev = page.get_real_rev()
        return str(rev)
        
def getHTML( old, iconimg, id, rev ):
    html = u"""<a href="?action=state&old=%(old)s&id=%(id)s&rev=%(rev)s">%(iconimg)s</a>""" % { "old" : old.upper(), "id" : id, "rev" : rev, "iconimg" : iconimg }
    return html
    
def getSmileyCode( state ):
    smileyname = statelist.get(state.lower(), statelist.get( Defaultstate ))
    return smileyname
        
def parsText( regex, source ):
    source = source.encode( "iso-8859-1" )
    variable = re.search( regex, source )
    if variable != None:
        variable = variable.group( 1 )
        value = variable.decode( "iso-8859-1" )
    else:
        return 0
    return value

def validState( state = "todo" ):
    if state and ( type( state ) == str ):
        state = state.strip()
        if state.lower() in statelist:
            return state.lower()
    return Defaultstate.lower()
    
def execute(macro, args):
    return State(macro, args).renderInPage()