"""
Name: renderbox
Title: RenderBox
Author: Cooper
Date: 18/03/2019

Desc:  This is just a simple wrapper for RenderBox allowing it to be called with the appropriate parameters and
getting back a render.  Nothing complicated.

XT Output as of version XT-Build403-Davide-2-onion

Usage: xt [--about] [--rtl|--ltr] [--sign=WxH] [--cp=n] [--list] [-M[elz][fr][:rr]] [-Fumra] [-Ocdhmvr] [-Dgtumc] [-d] [-r] [-u] font-library [-c text | file | -]
  --ltr|--rtl       base text direction (default: automatic)
  --sign=WxH        sign size (default 144x19
  --cp=n            codepage (default: 0, unicode)
  --list            lists the supported sign sizes, and contents of the font library
  -M[elz][fr][:rr]  font mapper: e, l, z order; font ratio; route ratio (default e66:85)
  -Fumra            shaper flags: u no undefined, r no mirroring, m no marks, a arabic digits
  -Dgtumc           shaper debug: g glyphs, t trace, u show undefined, m show marks, c show controls
  -Ocdhmvr          options: c classic, d debug, h hex bitmap, m no multipage, v no vertical centring, r no space reduction
  -d                debug: displays debugging information instead of output
  -r                render: renders a bitmap instead of SuperX
  -u                unescape: convert \'xx to byte

Usage: sxtrans [--about] [--list] [options] font-library -c text|file|- file|-
Options:
  --sign=WxH
            sign size (default 144x19)
  --conf=file
            load configuration file
  --stock
            create a stock sign (default)
  --custom
            create a custom sign
  --composite
            generate a SuperX composite image
  --bitmap
            generate a Bitmap composite image
  --meta
            generate metadata
  --hex
            ascii-hex images (default)
  --bin
            binary images
  --ltr|--rtl
            base text direction (default automatic)
  --cp=n
            codepage (default 0 UTF8)
  -M[ez][fr][:rr]
            font mapper;
            E (default) or Z order
            fr; font ratio (default 66%)
            rr; route ratio (default 85%)
  -Odbhmsv
            translator options: d debug, h hex bitmap, b binary bitmap, m no multipage,
            s space reduction, v no vertical centering
  -Dcgmtu
            shaper debug: c show controls, g missing glyphs,
            m show marks, t trace, u show undefined
  -Famru
            shaper flags: a arabic digits, m no marks,
            r no mirroring, u no undefined
  -d
            display debugging information
  -r
            render as a bitmap (see --bitmap)
  -s
            silent
  -u
            unescape \\xhh
File:
  -c text|file|-
            read from the command line, a file or pipe
  file|-
            write to a file or pipe

"""
import logging
import subprocess

class RenderBox(object):
    def __init__(self, config_dict):
        self.config_dict = config_dict

        self.xt_path = "/usr/bin/xt"
        self.sx_path = self.config_dict.get("RENDERBOX_sx_path", "/usr/bin/sxtrans")

    """
    ###################################################################################################################
    Renderbox calls
    """

    def getSuperXRender(self, sign_size: str, font_path: str, font_map: str, message: str, use_sx: bool = False, filter = None) -> str:
        """
        Converts SuperX UTF-8 text into an SuperX graphic, using parameters defined below

        :param sign_size: Resolution of the sign including colour panel
        :param font_path: Path of the fontlib
        :param font_map: Font Mapping for Renderbox
        :param message: Message to Render
        :param use_sx: Uses SXTrans instead of the original XT, default is to use XT
        :param filter: Stuff to filter out in the resulting render as it can sometimes break the sign
        :return:
        """
        if use_sx:
            rbpath = self.sx_path
        else:
            rbpath = self.xt_path

        command = [rbpath,
                    "--sign=%s" % sign_size,
                    "-Oh",
                    "-M%s" % font_map,
                    font_path,
                    "-c", message,
                    "-"      #For some daft reason SX requires this, and XT will accept it
                   ]

        logging.debug(" ".join(command))

        try:
            process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            output, error = process.communicate()
        except FileNotFoundError:
            return ""

        if filter is None:
            return output.decode("utf-8")
        else:
            return self.filter_output(output, filter)


    def getBasicXRender(self, sign_size: str, font_path: str, font_map: str, message: str, use_sx: bool = False) -> str:
        """
        Converts SuperX UTF-8 text into a basicX compatible bitmap graphic, using parameters defined below.
        This does not create the entire basicX string like the superx counterpart does.

        :param sign_size: Resolution of the sign including colour panel
        :param font_path: Path of the fontlib
        :param font_map: Font Mapping for Renderbox
        :param message: Message to Render
        :return:
        """
        if use_sx:
            rbpath = self.sx_path
        else:
            rbpath = self.xt_path

        command = [rbpath,
                   "--sign=%s" % sign_size,
                   "-Oh",
                   "-M%s" % font_map,
                   "-r",    #We need to generate a bitmap of the whole thing because superx modes are not supported.
                   font_path,
                   "-c", message,
                   "-"  # For some daft reason SX requires this, and XT will accept it
                   ]

        logging.debug(" ".join(command))

        try:
            process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            output, error = process.communicate()
        except FileNotFoundError:
            return ""

        # This is the resulting hex string which also contains the bitmap header which needs to be stripped (4 bytes, 8 nibbles)
        bitmap_hex_string = output.hex().upper()
        graphic_hex_string = bitmap_hex_string[8:]

        # There is no need to do any filtering as this is a bitmap
        return graphic_hex_string


    """
    ###################################################################################################################
    Other calls
    """
    def check_render_is_scrolling(self):
        """
        Maybe at some point this is needed but for now it is just a placeholder.
        """
        pass

    def filter_output(self, render, elements_to_filter):
        """
        Replacements specific undesired elements, this just filters out!!
        """
        _render = render.decode("utf-8")

        if type(elements_to_filter) is list:
            for element in elements_to_filter:
                # print(element)
                _render = _render.replace(element, "")
        elif type(elements_to_filter) is str:
            _render = _render.replace(elements_to_filter, "")

        return _render

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)

    config_dict = {

    }

    rb = RenderBox(config_dict)

    print("XT Render")
    render = rb.getSuperXRender("144x19", "/usr/share/renderbox/fontlib.bin", "e66:85", "{\mode0 Hello World {أبو ظبي}}")
    print(render)

    print("\nSX Render")
    render = rb.getSuperXRender("144x19", "/usr/share/renderbox/fontlib.bin", "e66:85", "{\mode0 Hello World {أبو ظبي}}", use_sx=True)
    print(render)

    print("\nBasicX Render")
    render = rb.getBasicXRender("144x19", "/usr/share/renderbox/fontlib-dot.bin", "e66:85", r"{\mode2{1}\fs{الله أكبر}}")
    print(render)