import cgi
from persistent import Persistent
from persistent.list import PersistentList
from persistent.dict import PersistentDict

from util import RSTtoHTML, BBtoHTML

from StringIO import StringIO

class Response:
    def __init__(self, http_status='200 OK', http_headers={}):
        self.http_status = http_status
        self.http_headers = http_headers
        self._buffer = StringIO()

    def write(self, instr):
        self._buffer.write(instr)

    def read(self):
        return self._buffer.getvalue()

    def __del__(self):
        self._buffer.close()

    def setHeader(self, key, value):
        self.http_headers[key]=value

    def getHeaders(self):
        return self.http_headers.items()

    def redirect(self, target_url, temporary = False):
        if not temporary:
            self.http_status = '301 Moved Permanently'
        else:
            self.http_status = '302 Found'
        self.setHeader('Location', target_url)


class Entry(Persistent):
    '''
    The Entry object, representing a blog entry and its data.
    Don't create this object itself, use storage.EntryFactory instead.
    '''
    title = ''
    data = ''
    author = ''
    summary = ''
    date = ''
    datatype = ''
    key = ''
    comments = PersistentList([])
    
    def __init__(self, title, data, summary, author, date, datatype='RST', key=None):
        self.title = cgi.escape(title)
        self.data = data
        self.author = author
        if type(self.author) is str:
           self.author = cgi.escape(self.author)
        self.summary = summary
        self.date = date
        self.datatype = datatype
        self.key = key
        self.comments = PersistentList([])

    @property
    def htmldata(self):
        if self.datatype == 'RST':
            return RSTtoHTML(self.data)
        elif self.datatype == 'BBCode':
            return BBtoHTML(self.data)
        elif self.datatype == 'HTML':
            from warnings import warn
            warn('HTML is deprecated and unsafe. Don\'t use it.')
            return self.data        
        raise NotImplementedError('Only RST and BBCode are implemented!')

class Comment(Persistent):
    '''
    The Comment object, representing a comment in the blog.
    Don't create this object itself, use storage.CommentFactory instead.
    '''
    def __init__(self, data, author, date, entry, datatype='RST'):
        self.data = data
        self.author = author
        if type(self.author) is str:
           self.author = cgi.escape(self.author) 
        self.date = date
        self.entry = entry
        self.datatype = datatype

    @property
    def htmldata(self):
        if self.datatype == 'RST':
            return RSTtoHTML(self.data)
        elif self.datatype == 'BBCode':
            return BBtoHTML(self.data)
        elif self.datatype == 'HTML':
            from warnings import warn
            warn('HTML is deprecated and unsafe. Don\'t use it.')
            return self.data        
        
        raise NotImplementedError('Only RST and BBCode are implemented!')

    @property
    def index(self):
        pos = self.entry.comments.index(self)
        pos += 1  # Make the index user-readable
        return "comment-%s" % pos

class User(Persistent):
    '''
    The User object, representing a user of the blog, and storing authentication
    info. Don't create this object itself, use storage.UserFactory instead.
    '''
    def __init__(self, username, nickname, hexpasshash, clearance, homepage=''):
        self.username = username
        self.nickname = cgi.escape(nickname)
        self.passhash = hexpasshash
        self.clearance = clearance
        self.homepage = homepage
        self.comments = []

    def __str__(self):
        ''' To make Users be able to just be outputted into templates. '''
        return self.nickname


class Upload(Persistent):
    '''
    The Upload object, representing a user-uploaded file.
    Don't create this object itself, use storage.UploadFactory instead.
    '''

    def __init__(self, id, data, datatype, owner):
        self.id = id
        self.data = data
        self.datatype = datatype
        self.owner = owner

class Poll(Persistent):
    ''' The Poll object, for registering polls and their votes. '''

    author = ''
    question = ''
    date = None
    options = PersistentDict({})
    votes = PersistentDict({})
    
    def __init__(self, id, author, date, question, options):
        self.id = id
        self.author = author
        self.question = question
        self.date = date

        self.options = PersistentDict({})
        self.options.update(options)
 
        self.votes = PersistentDict({})
        
    def vote(self, user, optionid):
        self.votes[user.username] = optionid

    def unvote(self, user):
        del self.votes[user.username]

    @property
    def option_ids(self):
        return self.options.keys()

    def tally(self,optionid, percent=False):
        num = self.votes.values().count(optionid)
        if not percent:
            return num
        return float(num)/len(self.votes.values())

    def allTally(self,percent=False):
        results = {}
        for id in self.options:
            num = self.tally(id,percent=percent)
            results[id]=num
        return results
    
    
