# -*- coding: utf-8 -*-
"""
    MoinMoin - Asciinema

    This macro allows to attach asciinema cast-files to a page and
    play them. Maybe you like it, too.
    
    Based on and inspired by:
    https://github.com/asciinema/asciinema-player

    Thanks for this cool set of tools to the asciinema-project!
    Thanks for MoinMoin!

    The github page also documents all the asciinema-player options.
    (I just snake_cased the options for the plugin).

    Installation:
    1. Drop the latest release (.js+.css) of the following github-repo
       into your static files (Probably into:
       "/usr/share/moin/htdocs/asciinema")
    2. Drop the macro in your site-specific "data/plugin/macro" directory.
    3. Restart server.
    4. Attach .cast file to site.
    5. Use macro.
    
    
    Usage:
    <<Asciinema(attached_file.cast, pagename, theme, cols, rows
        autoplay, preload, loop, start_at,
	speed, poster, font_size,
	title, author, author_url, author_img_url)>>

    Some hints:
    cols=([80]|Num)
    rows=([24]|Num)
    
    font-size=([small]|medium|big|Num(px,em,…)
    
    poster=(npt:mm:ss|"data:text/plain,Poster text")
    
    theme=([asciinema]|tango|solarized-dark|solarized-light|monokai)

    @copyright: 2019 Tobias Stein
    @license: GNU GPLv2 or later

    I'm not a frontend-, web- or python-programmer,
    i just wanted to have sth. like this.
    If you like - your free to improve code quality.

    No warranty for nothing, usage on your on own responsibility.

    Changelog:
    * 1.0:
      * Working implementation
      * Probably vulnerable to javescript injection
      	"author_url" and "author_img_url"
"""

import re
from MoinMoin import wikiutil
from MoinMoin.action.AttachFile import getAttachUrl, getFilename, exists
from MoinMoin.Page import Page

generates_headings = False

def macro_Asciinema(
	macro, filename=None, pagename=None,
	theme=None, cols=None, rows=24,
	autoplay=None, preload=None, loop=None, start_at=None,
	speed="1.0", poster="npt:1", font_size="small",
	title="Asciinema", author=None, author_url=None, author_img_url=None):

    if not pagename:
        pagename = macro.formatter.page.page_name

    request = macro.request
    formatter = macro.formatter

    if not exists(request, pagename, filename):
    	return formatter.text(
		'Attachment "%s" does not exist on page "%s"'
		% (filename, pagename))
    else:
	
	src=getAttachUrl(pagename, filename, request)
	player_opts = []
	if theme is not None:
		pattern = re.compile("^(asciinema|tango|solarized-dark|solarized-light|monokai)$")
		if pattern.match(theme):
			player_opts.extend([formatter.rawHTML('theme="%s"' % theme)])
		else:
    			return formatter.text(
				'Theme is unknown.')
	if rows is not None:
		if isinstance(rows, int):
			player_opts.extend([formatter.rawHTML('rows="%s"' % rows)])
		else:
		    return formatter.text(
			'Unable to determine rows.')
	if cols is not None:
		if isinstance(rows, int):
			player_opts.extend([formatter.rawHTML('cols="%s"' % cols)])
		else:
		    return formatter.text(
			'Unable to determine cols.')
	if autoplay is not None:
		player_opts.extend([formatter.rawHTML('autoplay="%s"' % True)])
	if preload is not None:
		player_opts.extend([formatter.rawHTML('preload="%s"' % True)])
	if loop is not None:
		player_opts.extend([formatter.rawHTML('loop="%s"' % True)])
	if start_at is not None:
		player_opts.extend([formatter.rawHTML('start-at="%s"' % start_at)])
	if speed is not None:
		if isinstance(speed, (int, float)):
			player_opts.extend([formatter.rawHTML('speed="%s"' % speed)])
		elif isinstance(float(speed), (int, float)):
			player_opts.extend([formatter.rawHTML('speed="%s"' % float(speed))])
		else:
		    return formatter.text(
			'Unable to determine speed.')
	if poster is not None:
		player_opts.extend([formatter.rawHTML('poster="%s"' % poster)])
	if font_size is not None:
		pattern = re.compile("^(small|medium|big|\d\+(px|r?em))$")
		if pattern.match(font_size):
		    player_opts.extend([formatter.rawHTML('font-size="%s"' % font_size)])
		else:
		    return formatter.text(
			'Unable to determine font-size.')
	if title is not None:
		title_html = wikiutil.escape(title)
		title_html = title_html.strip()
		player_opts.extend([formatter.rawHTML('title="%s"' % title_html)])
	if author is not None:
		author_html = wikiutil.escape(author)
		author_html = author_html.strip()
		player_opts.extend([formatter.rawHTML('author="%s"' % author_html)])
	if author_url is not None:
		player_opts.extend([formatter.rawHTML('author-url="%s"' % author_url)])
	if author_img_url is not None:
		player_opts.extend([formatter.rawHTML('author-img-url="%s"' % author_img_url)])

	ret = []
	ret.extend([formatter.rawHTML(asciinemaRessource(request, "asciinema-player", "css"))])
	ret.extend([formatter.rawHTML(asciinemaRessource(request, "asciinema-player", "js"))])
	ret.extend([formatter.rawHTML(
		'<asciinema-player %s src="%s"></asciinema-player>' %
		(' '.join(player_opts), src))])

	return ''.join(ret)


def asciinemaRessource(request, name, suffix):
    """ Format external script html """
    uri = '%s/asciinema/%s.%s' % (request.cfg.url_prefix_static, name, suffix)
    if suffix == 'css':
	tag = '<link rel="stylesheet" type="text/css" media="all" href="%s">' % uri
    if suffix == 'js':
	tag = '<script type="text/javascript" src="%s"></script>' % uri
    return tag
