from flask import Flask , request, send_from_directory, jsonify
from werkzeug.routing import BaseConverter
import random
import re
from flask_socketio import SocketIO, send, emit, join_room, leave_room
import eventlet
app = Flask(__name__,static_url_path='')
socketio = SocketIO(app)
class Object(object):
    pass
class RegexConverter(BaseConverter):
    def __init__(self, url_map, *items):
        super(RegexConverter, self).__init__(url_map)
        self.regex = items[0]

app.url_map.converters['regex'] = RegexConverter

@app.route('/')
def root():
    return app.send_static_file('eon.html');
@socketio.on('join')
def on_join(data):
    username = data['username']
    room = data['room']
    join_room(room)
    send(username + ' has entered the room.', room=room)

@socketio.on('leave')
def on_leave(data):
    username = data['username']
    room = data['room']
    leave_room(room)
    send(username + ' has left the room.', room=room)
@socketio.on('dicerollrequest')
def handle_diceroll(json):
    if re.match(r"(?:ob)?\d{1,2}t\d{1,3}(?:\+\d{1,2})?", json['roll']) is not None:
        (diceresult,ob,modifier) = roll_dices(json['roll'])
        response = {"username": json['username'],"dices": diceresult,"obcount":ob,"dicesum": sum(diceresult)+modifier,"modifier": modifier}
        emit("dicerollresponse",response,room=json['room'])

@app.route('/js/<path:path>')
def send_js(path):
    return send_from_directory('js',path)

@app.route('/css/<path:path>')
def send_css(path):
    return send_from_directory('css',path)

@app.route('/roll/<regex("(?:ob)?\d{1,2}t\d{1,3}(?:\+\d{1,2})?"):dices>')
def get_dice_roll(dices):
    (diceresult,ob,modifier) = roll_dices(dices)
    return jsonify(dices=diceresult,obcount=ob,dicesum=sum(diceresult)+modifier,modifier=modifier)

def roll_dices(dices):
    res = re.findall(r"(?:ob)?(\d{1,2})t(\d{1,3})(?:\+(\d{1,2}))?",dices)
    diceAmount = int(res[0][0])
    diceType = int(res[0][1])
    diceMod = int(res[0][2] or '0')
    if(diceType == 6 and dices.startswith("ob")):
        return roll_obthrow(diceAmount) + (diceMod,)
    return roll_normalthrow(diceAmount,diceType) + (diceMod,)

def roll_obthrow(diceAmount):
    diceType = 6
    return solve_ob(diceType,  [roll_dice(diceType) for x in range(diceAmount)])

def roll_normalthrow(diceAmount, diceType):
    return([roll_dice(diceType) for x in range(diceAmount)],0)


def solve_ob(t,dices):
    obCount = 0
    while 6 in dices:
        sixes = [i for i, x in enumerate(dices) if x == 6]
        obCount += len(sixes)
        for six in sixes:
            dices.extend([roll_dice(t),roll_dice(t)])
        dices = [i for j, i in enumerate(dices) if j not in sixes]
    return (dices,obCount)

def roll_dice(t):
    return random.randint(1,t)

if __name__ == '__main__':
    socketio.run(app)
