import re
import os
import sys
import BaseHTTPServer
import cgi
import cgitb
from CGIHTTPServer import CGIHTTPRequestHandler

# Request handlers
import browse
import playlist
import player
import Version

jukeboxState = None

class MyFieldStorage(cgi.FieldStorage):

    def __init__(self):
        self.list = []

    def append(self, item):
        self.list.append(item)

class HttpRequestHandler(CGIHTTPRequestHandler):

    __internal_path = '/jukebox/'

    def __init__(self, a, b, c):
        global jukeboxState
        self.state = jukeboxState

        CGIHTTPRequestHandler.__init__(self, a, b, c)

    def __absPath(self):
        s = self.path.split("?")
        return s[0]

    def queryParams(self):
        s = self.path.split("?")
        if len(s) <= 1:
            return {}
        else:
            return cgi.parse_qs(s[1])

    def __getFormFields(self):
        qs = self.rfile.read(int(self.headers.getheader('content-length')))
        self.form = MyFieldStorage()
        for key, value in cgi.parse_qsl(qs):
            self.form.append(cgi.MiniFieldStorage(key, value))

    def is_internal(self):
        p = re.compile('^' + self.__internal_path)
        return p.match(self.path)

    def do_HEAD(self):
        if self.is_internal():
            self.send_response(501)
        else:
            CGIHTTPRequestHandler.do_HEAD(self);
            
    def __do_internal(self):
        h = cgitb.Hook(file=self.wfile)
        urls =  {
            'browse': browse,
            'player': player,
            'playlist': playlist,
            'version': Version
        }
        p = self.__absPath()
        key = p[len(self.__internal_path):]
        if urls.has_key(key):
            if self.command == 'POST':
                self.__getFormFields()
            try:
                urls[key].serve(self)
            except:
                h.handle((sys.exc_type, sys.exc_value, sys.exc_traceback))
                self.wfile.write("<h1>Please report this bug</h1><p>Please <a href='http://developer.berlios.de/bugs/?group_id=3555'>report a bug using the Web interface</a>. Thank you!</p></body></html>")
        else:
            self.send_response(404)

    def do_GET(self):
        if self.is_internal():
            self.__do_internal()
        else:
            CGIHTTPRequestHandler.do_GET(self);

    def do_POST(self):
        if self.is_internal():
            self.__do_internal()
        else:
            CGIHTTPRequestHandler.do_POST(self);

    def serve_string(self, s):
        self.send_response(200)
        self.wfile.write(s)

    def send_root_file(self, path, cache, default):
        ctype = self.guess_type(path)
        if ctype.startswith('text/'):
            mode = 'r'
        else:
            mode = 'rb'
        try:
            f = open(path, mode)
        except IOError:
            self.send_error(404, "File not found")
        self.send_response(200)
        if ctype == "application/octet-stream":
            ctype = default
        self.send_header("Content-type", ctype)
        self.send_header("Content-Length", str(os.fstat(f.fileno())[6]))
        self.send_header("Cache-Control", "max-age=%s" % cache)
        self.end_headers()
        self.copyfile(f, self.wfile)
        f.close()

class HttpServer:

    def __init__(self, state, port = 4475):
        global jukeboxState
        jukeboxState = state
        os.chdir(os.path.dirname(sys.argv[0]) + '/www')
        self.__server = BaseHTTPServer.HTTPServer(('',port), HttpRequestHandler)
    def serve(self):
        self.__server.serve_forever()

