from __future__ import division

from textwrap import dedent
import random

from flask import render_template_string, g, render_template, session
from jinja2 import Markup
from pygments.formatters.html import HtmlFormatter
from pygments.lexers import get_lexer_by_name
import pygments

from pydrill import app
from pydrill import gen


@app.template_filter()
def render_question(question):
    return Markup(render_template(
        'question.html', question=question, vars=get_template_vars(question)))


@app.template_filter()
def render_explained_question(question, given_answer):
    return Markup(render_template(
        'explained_question.html', question=question, given_answer=given_answer,
        vars=get_template_vars(question)
    ))


def get_template_vars(question):
    template = app.jinja_env.from_string(question.text)
    random.seed(g.seed)
    return vars(template.module)


@app.template_filter()
def render(template, vars={}):
    random.seed(g.seed)
    return Markup(render_template_string(template, **vars))


@app.template_filter()
def in_random_order(iterable):
    items = list(iterable)
    random.shuffle(items)
    return items


def highlight_with_css_class(s, language, css_class):
    formatter = HtmlFormatter(cssclass=css_class)
    # TODO: can we do without strip?
    return pygments.highlight(dedent(unicode(s)), get_lexer_by_name(language),
                              formatter).strip()


@app.template_filter()
def highlight(s, language='python'):
    return highlight_with_css_class(s, language, 'highlight')


@app.template_filter()
def highlight_inline(s, language='python'):
    return highlight_with_css_class(s, language, 'highlight-inline')


@app.template_filter()
def get_answer_message(answer_is_correct):
    if answer_is_correct:
        return 'right!'
    return 'wrong!'


@app.template_filter('repr')
def repr_filter(obj):
    return repr(obj)


@app.template_filter()
def get_score_text(rank, num_users):
    num_better = rank - 1
    num_worse = num_users - rank
    if not num_better:
        return 'top 1%'
    if num_worse > num_better:
        return 'top {:.0%}'.format(1 - num_worse / num_users)
    elif num_better == num_worse:
        return 'top 50%'
    else:
        return 'bottom {:.0%}'.format(1 - num_better / num_users)


@app.template_global()
def get_prev_answer():
    return session.pop('prev_answer', None)


app.jinja_env.add_extension('jinja2.ext.do')
app.jinja_env.globals.update(gen=gen)

@@ -328,16 +328,45 @@
 rt gen%0A%0A
+DEFAULT_LANGUAGE = 'python'%0A%0A
 %0A@app.te
@@ -973,12 +973,53 @@
 ars=
+None):%0A    if vars is None:%0A        vars = 
 %7B%7D
-):
 %0A   
@@ -1159,21 +1159,19 @@
 e):%0A    
-items
+seq
  = list(
@@ -1199,21 +1199,19 @@
 shuffle(
-items
+seq
 )%0A    re
@@ -1219,13 +1219,11 @@
 urn 
-items
+seq
 %0A%0A%0Ad
@@ -1537,32 +1537,40 @@
 s, language=
-'python'
+DEFAULT_LANGUAGE
 ):%0A    retur
@@ -1680,24 +1680,32 @@
 anguage=
-'python'
+DEFAULT_LANGUAGE
 ):%0A    r
@@ -2143,16 +2143,14 @@
 urn 
-'
 top
- 1%25'
+(1)
 %0A   
@@ -2196,27 +2196,27 @@
 urn 
-'
 top
- %7B:.0%25%7D'.format
+(make_percentage
 (1 -
@@ -2238,16 +2238,17 @@
 m_users)
+)
 %0A    eli
@@ -2293,17 +2293,15 @@
 urn 
-'
 top
- 50%25'
+(50)
 %0A   
@@ -2326,30 +2326,30 @@
 urn 
-'
 bottom
- %7B:.0%25%7D'.format
+(make_percentage
 (1 -
@@ -2372,16 +2372,203 @@
 m_users)
+)%0A%0A%0Adef top(percentage):%0A    return 'top %7B:d%7D%25'.format(percentage)%0A%0A%0Adef bottom(percentage):%0A    return 'bottom %7B:d%7D%25'.format(percentage)%0A%0A%0Adef make_percentage(n):%0A    return int(100 * n)
 %0A%0A%0A@app.

Clean up jinja_env helpers