import security
from util import runTemplate

class ViewletBase(object):
    ''' Abstract class for page views. '''
    template = None  # String path to location of template
    searchList = {}
    traverseOverrideView = None
        
    def __init__(self, view):
        self.view = view

        self.searchList = {}

        self.searchList.update(self.view.searchList)

    def __call__(self):
        ''' Default __call__ '''
        content = runTemplate(self.template, self.searchList)

        return content

class LogInViewlet(ViewletBase):
    template = "templates/login_viewlet.tmpl"
    
    def __init__(self, view):
        super(LogInViewlet, self).__init__(view)
        
    def performLogIn(self):
        username = self.view.fields.get('username', '')
        password = self.view.fields.get('password', '')
        good = security.logIn(username, password, self.view.session)
        if good:
            self.searchList['warning'] = ""
        else:
            self.searchList['warning'] = "Wrong Username or Password."
        

    def performLogOut(self):
        security.logIn('','',self.view.session, logout=True)
        
    def __call__(self):
        self.searchList['warning'] = ''
        statechange = False
        if 'logout' in self.view.fields:
            self.performLogOut()
            statechange = True
        elif 'FORM_SUBMITTED' in self.view.fields:
            self.performLogIn()
            statechange = True
        if statechange:
            self.view.user = security.currentUser(self.view.session)
            self.view.searchList['user'] = self.view.user
            self.searchList.update(self.view.searchList)
            
        return super(LogInViewlet, self).__call__()


class PollViewlet(ViewletBase):
    template = 'templates/poll_viewlet.tmpl'

    def __init__(self, view):
        super(PollViewlet, self).__init__(view)
        self.poll = view.root.getPoll()
        self.can_vote = ((self.view.user) and
                         (self.view.user.clearance >= security.REGULAR))
        self.has_voted = False
        self.my_option = None
        if self.can_vote and self.poll:
            assert self.view.user
            if self.view.user.username in self.poll.votes:
                self.has_voted = True
                self.my_option = self.poll.votes[self.view.user.username]
        self.see_results = self.has_voted or not self.can_vote

    def performVote(self):
        option = self.view.fields.get('vote',None)
        if (self.can_vote and
            not self.has_voted and
            option in self.poll.options): # if the request is good
            
            self.poll.vote(self.view.user, option)
            self.has_voted = True
            self.can_vote = False
            self.my_option = self.poll.votes[self.view.user.username]
            self.see_results = True

    def performUnVote(self):
        if (self.can_vote and self.has_voted):

            self.poll.unvote(self.view.user)
            self.can_vote = ((self.view.user) and
                             (self.view.user.clearance >= security.REGULAR))
            self.has_voted = False
            self.my_option = None
            self.see_results = not self.can_vote
            
    def __call__(self):
        if not self.poll:
            return ''
        if 'vote' in self.view.fields:
            self.performVote()
        elif 'unvote' in self.view.fields:
            self.performUnVote()

        self.searchList.update({
                'poll': self.poll,
                'can_vote': self.can_vote,
                'has_voted': self.has_voted,
                'show_results': self.has_voted,
                'my_option': self.my_option
                })

        if 'results' in self.view.fields or self.see_results:
            self.see_results = True
            tally = self.poll.allTally()
            self.searchList.update({
                'tally': tally,
                'show_results': True
                })
        return super(PollViewlet,self).__call__()

viewlets_available = [LogInViewlet, PollViewlet]
