from __future__ import absolute_import

import pylons, tg
from paste.deploy.converters import asbool
from repoze.what.predicates import in_any_group

from bazbase import structure, conversion, flavors
from bazbase import custom as bazcust

# Customization hooks for Bazki

import os, cgi

# These are passed to templates for a given format from getters
# TODO(xavid): this geometry should be Gameki-specific.
# TODO(xavid): most of these should probably be required in bazki.sty
def get_template_parameters(format, deps):
    if format == 'tex':
        hmargin = '.25in'
        tmargin = '.4in'
        bmargin = '.25in'
        headsep = '6pt'
        config = structure.get_element(u'LayoutConfig')
        if config is not None:
            deps.addPropvalDep(config, u'hmargin')
            hpv = config.get_propval(u'hmargin')
            if hpv and hpv.value:
                hmargin = hpv.value
            deps.addPropvalDep(config, u'tmargin')
            tpv = config.get_propval(u'tmargin')
            if tpv and tpv.value:
                tmargin = tpv.value
            deps.addPropvalDep(config, u'bmargin')
            bpv = config.get_propval(u'bmargin')
            if bpv and bpv.value:
                bmargin = bpv.value
            deps.addPropvalDep(config, u'headsep')
            hspv = config.get_propval(u'headsep')
            if hspv and hspv.value:
                headsep = hspv.value
        else:
            deps.addExistsDep(u'LayoutConfig')

        from .fonts import fontdir, fontargs, DEFAULTS, FONTS, NAME_TO_FONT

        preamble = [
            r'\usepackage{fontspec}',
            r'\usepackage{xunicode}',
            r'\defaultfontfeatures{Mapping=tex-text}',
            #r'\usepackage[CJK,Latin]{ucharclasses}', --doesn't work on scripts
            #r'\setDefaultTransitions{\fontspec{DejaVu Serif}}{}',
            #r'\setTransitionsForJapanese{\fontspec{Sazanami Mincho}}{}',
            
            r'\usepackage[hmargin=%s,vmargin={%s,%s},headsep=%s]{geometry}'
            % (hmargin, tmargin, bmargin, headsep),
            #r'\usepackage{pslatex}',
            r'\usepackage{subscript}',
            r'\usepackage{hyperref}',
            r'\usepackage{fancyhdr}',
            #r'\usepackage{pifont}',
            #r'\usepackage[postscript]{ucs}',
            #r'\usepackage[utf8x]{inputenx}',
            #r'\usepackage[T1]{fontenc}',
            r'\usepackage{graphicx}',
            #r'\usepackage[usenames,dvipsnames,svgnames,table]{xcolor}',
            r'\usepackage[usenames,dvipsnames,svgnames]{xcolor}',
            r'\usepackage{verbatim}',
            r'\usepackage{multicol}',
            #r'\usepackage{tabulary}',
            r'\usepackage{tabularx}',
            #r'\usepackage{latexsym}',
            #r'\usepackage{amssymb}',
            #r'\usepackage{textcomp}',
            r'\usepackage{bazki}',
            r'\pagestyle{fancy}',
            r'\lhead{}',
            r'\rhead{}',
            #r'\cfoot{\thepage}',
            r'\cfoot{}',
            r'\renewcommand{\headrule}{}',
            
            r'\newfontfamily\japanese[ExternalLocation=%s]{HanaMinA}' % fontdir,
            r'\newfontfamily\japaneseext[ExternalLocation=%s]{HanaMinB}' % fontdir,
            #r'\newfontfamily{\symbol}{Apple Symbols}',
            r'\newfontfamily{\symbol}[%s]{DejaVuSans}' % fontargs,
            #r'\newfontfamily{\dingbat}{Zapf Dingbats}'
        ]

        fonts = dict(DEFAULTS)
        fc = structure.get_element(u'FontConfig')
        if fc is not None:
            for f in fonts:
                if fc.haspropval(f + 'font'):
                    fonts[f] = NAME_TO_FONT[fc.getprop(f + 'font')]
        for f in fonts:
            if f in ('main', 'sans', 'mono'):
                preamble.append(r'\set%sfont[%s]{%s}' % (f, FONTS[fonts[f]],
                                                         fonts[f]))
            else:
                preamble.append(r'\newfontfamily{\%s}[%s]{%s}'
                                % (f, FONTS[fonts[f]], fonts[f]))
            
        return {'preamble_lines': preamble}
    else:
        return {}

# Paths to search for packages
# As with normal TEXINPUTS, use // at the end to search recursively, and
# include the empty string to search default paths
LATEX_SEARCH_PATHS = [
    os.path.join(os.path.dirname(__file__), 'LaTeX')+"//",
    '']

# Additional functions whose return values will be added to the HTML
# head.  This can be used to specify extra CSS files to include in
# both edit and product pages.
EXTRA_HEAD_GENERATORS = []

OMNISCIENT_PRED = in_any_group(u'Admin',
                               msg='Only Admins can edit this website!')
EDITOR_PRED = OMNISCIENT_PRED

GROUPS = [u'Admin']

USER_ANCESTOR = u'User'

def is_editor(environ=None):
    if environ is None:
        try:
            environ = pylons.request.environ
        except TypeError:
            # This should only be the case run from the command-line.
            return True
    return EDITOR_PRED.is_met(environ)

def is_omniscient(environ=None):
    if environ is None:
        try:
            environ = pylons.request.environ
        except TypeError:
            # This should only be the case run from the command-line.
            return True
    return OMNISCIENT_PRED.is_met(environ)

# Custimizations of bazbase hooks
def set_up(app_name='Bazki'):
    bazcust.APP_NAME = app_name

    bazcust.is_omniscient = is_omniscient
    bazcust.EDITOR_ANCESTOR = u'Admin'

    # Link customization
    # cust wiki URLs
    def product_link(ename, pname, dependencies, render, extension=None,
                     args=None):
        assert ename is not None
        namep = u'name'
        e = structure.get_element(ename)
        if e is None:
            dependencies.addExistsDep(ename)
            return (ename, dict(url="", style='broken'))
        else:
            dependencies.addDep(e.get_propval(namep))
            from . import getting
            style = 'internal'
            info = {}
            if pname:
                filters = {}
                real_pname = conversion.extract_filters(pname, filters)
                dependencies.addPropvalDep(e, real_pname)
                flavor = structure.get_flavor(real_pname)
                if flavor is not None and flavor.binary:
                    if e.has_propval(real_pname):
                        if extension is not None and extension != 'default':
                            style = extension
                        else:
                            from bazbase import translators
                            style = e.get_propval(real_pname).format
                        if ename == u'SunDiscBanner':
                            assert style == '.png'
                        if 'd' in filters:
                            width, height, force = translators.parse_dimension(
                                filters['d'])
                            if width is not None and height is not None:
                                info['width'] = width
                                info['height'] = height
                                if force:
                                    info['force'] = True
                    else:
                        style = 'broken'
                url = getting.attachment_url_for(e, pname, dependencies, render,
                                                 type=extension)
                dispname = real_pname
            else:
                if getting.has_get_url(e, dependencies, render):
                    url = getting.get_url_for(e, dependencies, render,
                                              type=extension, args=args)
                else:
                    url = ""
                if not url:
                    style = 'broken'
                dispname = render(e, namep) if e.has_propval(namep) else e.ename
            info['style'] = style
            info['url'] = url
            return (dispname, info)
    bazcust.product_link = product_link
    def edit_link(ename, pname=None, dependencies=None,
                  render=conversion.render, extension=None):
        if pname:
            # Always use get for attachments
            return product_link(ename, pname, dependencies, render,
                                extension=extension)
        namep = u'name'
        e = structure.get_element(ename)
        if e is None:
            if dependencies:
                dependencies.addExistsDep(ename)
            style = 'broken'
            dispname = ename
        else:
            if dependencies:
                dependencies.addPropvalDep(e, namep)
            style = 'internal'
            if e.has_propval(namep):
                name = render(e, namep).strip() or e.ename
            else:
                name = e.ename
            dispname = ("%s (%s)" % (name, e.ename) if name != e.ename
                        else name)
        from . import translators
        return (dispname,
                dict(url=translators.edit_url(ename, dependencies,
                                              render=render),
                     style=style))
    bazcust.edit_link = edit_link
    def local_link(uri):
        from . import translators
        return translators.url(uri)
    bazcust.local_link = local_link

    _sqlalchemy_converters = {
        'url': str,
        'echo': asbool,
        'echo_pool': asbool,
        'pool_recycle': int
        }
    # pool_recycle was 1000, but that's too long for sql.mit.edu
    def get_sqlalchemy_args():
        ret = {'pool_recycle': 30,
               'echo': 0}
        for k, v in tg.config.items():
            if '.' in k and k.split(".",1)[0] == "sqlalchemy":
                key = k.split(".")[-1]
                if key in _sqlalchemy_converters:
                    ret[key] = _sqlalchemy_converters[key](v)
                else:
                    raise TypeError("Don't know how to interpret configuration parameter 'sqlalchemy.%s'!"%key)
        assert 'url' in ret and ret['url'] is not None, (ret, tg.config.items())

        return ret
    bazcust.get_sqlalchemy_args = get_sqlalchemy_args
