#!/usr/bin/python
import cgi, cgitb, sys, time, math
import MySQLdb
import dbname
import logon
import game2


def add_player(form,cur):
    uid = logon.logon(form,cur)
    if not uid:
        print '<p>login failed.'
        print '</html>'
        sys.exit()

    try:
        cur.execute("SELECT red, green, blue FROM users WHERE uid = %d" % uid)
        rows = cur.fetchall()
        if cur.rowcount==0:
            print '<p>user data not found'
            print '</html>'
            sys.exit()
        row = rows[0]
        username = form["username"].value
        password = form["password"].value
        player = form["player"].value
        if  not player: player="player"
        rs = (username, password, player, row[0], row[1], row[2])
        cur.execute("""INSERT INTO finalgame ( username, password, player, start, modified, moved,
        red, green, blue, status )
        VALUES (
        '%s', 
        '%s',
        '%s',
        now(),
        now(),
        now(),
        %d, %d, %d,
        'join'
        )""" % rs )
        print '<p>player <b>%s</b> has started the final exam.' % player
    except MySQLdb.Error, e:
       print e
       print '</html>'
       sys.exit()
       
def remove_player(form,cur):
    try:
        player = form['player'].value
        password = form['password'].value
        cur.execute("DELETE FROM finalgame WHERE player='%s' AND password='%s'" %
                (player,password) )
        print 'player <b>%s</b> removed from gameboard' % player
    except MySQLdb.Error, e:
        print e

def finish_game(cur,id):
    try:
        str = "UPDATE finalgame SET finish=now(), status='finished' where id=%d and status!='finished'" % id
        cur.execute(str);
    except MySQLdb.Error, e:
        print e        
        
       
def update_player(form,cur):
    try:
        player = form['player'].value
        password = form['password'].value
        vx=float(form['vx'].value)
        vy=float(form['vy'].value)
        # limit velocity to 140
        vn = math.hypot(vx,vy)/140.0
        if (vn>1.0):
            vx = vx/vn
            vy = vy/vn
        rs = (vx,vy,player,password)
        str = "UPDATE finalgame SET vx=%g, vy=%g, status='update', modified=now() where player='%s' and password='%s' and status!='finished'" % rs
        cur.execute(str);
        #print '<p>',str
        print '<p>player <b>%s</b> velocity set to (%s, %s)' % (player, vx, vy)
        print '</html>'
    except MySQLdb.Error, e:
        print e

def show_scores(cur):
    try:
        str="SELECT finish, start, player, collisions FROM finalgame WHERE status='finished'"
        cur.execute(str)
    except MySQLdb.Error, e:
        print e

    rows = cur.fetchall()
    fmt = '%Y-%m-%d %H:%M:%S'
    print '<pre>'
    for row in rows:
        finish = row[0]
        start = row[1]
        player = row[2]
        collisions = int(row[3])
        d2 = time.mktime(time.strptime(finish,fmt))
        d1 = time.mktime(time.strptime(start,fmt))
        diff = d2 - d1
        #print 'finish %s start %s d2 %d d1 %d diff %d' % (finish, start, d2, d1, diff)
        rs = (player, finish, diff, collisions)
        print '"%s" finished "%s"  in %d seconds with %d collisions' % rs
    print '</pre>'
 
def show_status(cur):
    try:
        cur.execute ("SELECT modified, player, red, green, blue, px, py, vx, vy, collisions, status, id FROM finalgame")
    except MySQLdb.Error, e:
        print e

    rows = cur.fetchall()
    print '<pre>'
    for row in rows:
        modified = row[0]
        player = row[1]
        red = int(row[2])
        green = int(row[3])
        blue = int(row[4])
        px = float(row[5])
        py = float(row[6])
        vx = float(row[7])
        vy = float(row[8])
        collisions = row[9]
        status = row[10]
        id = int(row[11])
        rs = (modified, player, id, red, green, blue, px, py, vx, vy, collisions, status)
        print '"%s" "%s" %d %d %d %d %g %g %g %g %s "%s"' % rs
    print '</pre>'
    
def move_player(cur, rs):
    try:
        str = """UPDATE finalgame SET moved='%s', mseconds=%g,
        px=%g, py=%g, vx=%g, vy=%g, collisions=%d WHERE id=%d and status!='finished'""" % rs
        cur.execute(str)
    except MySQLdb.Error, e:
        print e
        print '</html>' 
        sys.exit()
        
    
def play(cur,show):
    import time
    sn = time.time()
    now = time.localtime(sn)
    mseconds = sn - time.mktime(now)
    fmt = '%Y-%m-%d %H:%M:%S'
    now = time.strftime(fmt,now)
    d = time.strptime(now,fmt)
    sn = (d[3]*60+d[4])*60+d[5] + mseconds
    #dtn = datetime.datetime(*d[0:6])
   
    if show:
        print '<p>Datetime: '
        print now, mseconds

    try:
        cur.execute("SELECT moved, mseconds, id, px, py, vx, vy, collisions FROM finalgame")
    except MySQLdb.Error, e:
        print e
        print '</html>'
        sys.exit()
    rows = cur.fetchall()
    print '<p><pre>'
    for row in rows:
        moved = row[0]
        ms = float(row[1])
        d = time.strptime(moved,fmt)
        s = (d[3]*60+d[4])*60+d[5] + ms
        #dt = datetime.datetime(*d[0:6])
        diff =sn - s
        id = int(row[2])
        #print '%g id %d' % (diff,id)
        px = float(row[3])
        py = float(row[4])
        vx = float(row[5])
        vy = float(row[6])
        if (game2.targ.contains(px,py) and vx == 0 and vy == 0): finish_game(cur,id)
        collisions = int(row[7])
        ball = game2.Ball(17,px,py,vx,vy)
        ball.collisions = collisions;
        game2.update_ball(ball,0.5*diff)
        rs = (now, mseconds, ball.x, ball.y, ball.vx, ball.vy, ball.collisions, id)
        move_player(cur,rs)
        if show:
            print 'id %d %g %g %g %g %d' % (id, ball.x, ball.y, ball.vx, ball.vy, ball.collisions)
        
    print '</pre>'
    
    
    

#-------main program
cgitb.enable() # formats errors in HTML

sys.stderr = sys.stdout
print "Content-type: text/html"
print
print '<html>'


form = cgi.FieldStorage()
db = dbname.dbopen()
cur = db.cursor()

if form.has_key("action"): action = form["action"].value
else: action = 'status'

#print '<p>action: <b>%s</b>' % action

if action!='move': play(cur,False)
if action=='status': show_status(cur)
elif action=='move': play(cur,True)
elif action=='join': add_player(form,cur)
elif action=='update': update_player(form,cur)
elif action=='remove': remove_player(form,cur)
elif action=='scores': show_scores(cur)
else: print '<p>action <b>%s</b> not recognized' % action
print '</html>'
cur.close()
db.close()
