'''
Created on 08-Jun-2021

@author: bthakur
'''
from sympy import log, nsimplify
from xv.util import toIntOrFloat

class BivariateExpressions:
    def __init__(self, n1, n2):
        self.n1 = n1
        self.n2 = n2
        self.expr_tuples = self._init_expressions()
        pass

    def _init_expressions(self):
        n1 = self.n1
        n2 = self.n2
        exprs_temp1 = self._init_expr_tuples(n1, n2)
        exprs_temp2 = self._init_expr_tuples(n2, n1)

        exprs_temp = []
        for idx, expr in enumerate(exprs_temp1):
            exprs_temp.append(exprs_temp1[idx])
            exprs_temp.append(exprs_temp2[idx])
            pass

        unique_exprs = []
        exprs = []
        for expr in exprs_temp:
            if expr[1] in unique_exprs:
                continue

            #if hasattr(expr[0], '_repr_latex_'):
            #    label = f"${expr[1]}$ \t = \t ${expr[0]._repr_latex_().replace('$', '')}$"
            #else:
            #    label = f"${expr[1]}$ \t = \t ${expr[0]}$"
            #    pass

            result_label = self._get_latex_str(expr[0])
            exprs.append({
                 "expr": expr[1],
                 "result": toIntOrFloat(expr[0]),
                 "result_label": result_label
                })
            unique_exprs.append(expr[1])
            pass

        return exprs
        pass

    def get_exprs(self, regex = True):
        if regex:
            return [
                    f"${expr['expr']}$"
                    for expr in self.expr_tuples
                ]
        else:
            return [
                    expr['expr']
                    for expr in self.expr_tuples
                ]
        pass

    def get_results(self, regex = True):
        if regex:
            return [
                    f"${expr['result']}$"
                    for expr in self.expr_tuples
                ]
        else:
            return [
                    expr['result']
                    for expr in self.expr_tuples
                ]
        pass

    def get_result_labels(self, regex = True):
        if regex:
            return [
                    f"${expr['result_label']}$"
                    for expr in self.expr_tuples
                ]
        else:
            return [
                    expr['result_label']
                    for expr in self.expr_tuples
                ]
        pass

    def get_expr_and_result_labels(self, sep = "\t = \t"):
        return [
            f"${expr['expr']}$ {sep} ${expr['result_label']}$"
            for expr in self.expr_tuples
            ]
        pass


    def _init_expr_tuples(self, n1, n2):
        expr_tuples = self._init_expr_tuples_type1(n1, n2)
        expr_tuples = [(nsimplify(item[0], tolerance=10**-2), item[1])
                       for item in expr_tuples]
        return expr_tuples

    def _init_expr_tuples_type1(self, n1, n2):
        exprs_temp1 = [
            (n1, f"{n1}"),
            (n2, f"{n2}"),
            (-n1, f"-{n1}"),
            (-n2, f"-{n2}"),
            (n1 + n2, f"{n1} + {n2}"),
            (n1 - n2, f"{n1} - {n2}"),
            (-n1 + n2, f"{-n1} + {n2}"),
            (-n1 - n2, f"{-n1} - {n2}"),

            (n1 * n2, f"{n1} * {n2}"),
            (n1 * - n2, f"{n1} * ({-n2})"),
            (-n1 * n2, f"{-n1} * {n2}"),
            (-n1 * - n2, f"{-n1} * ({-n2})"),

            (n1 / n2, f"{n1} / {n2}"),
            (n1 / - n2, f"{n1} / ({-n2})"),
            (-n1 / n2, f"{-n1} / {n2}"),
            (-n1 / - n2, f"({-n1}) / ({-n2})"),

            (n1**n2, f"{{{n1}}}^{{{n2}}}"),
            (n1**(-n2), f"{{{n1}}}^{{{-n2}}}"),
            (-n1**n2, f"{{({-n1})}}^{{{n2}}}"),
            (-n1**(-n2), f"{{({-n1})}}^{{{-n2}}}"),

            (log(n1)/log(n2), f"log_{{{n2}}}{{{n1}}}"),
            #(log(n1)/log(-n2), f"log_{{{-n2}}}{{{n1}}}"),
            #(log(-n1)/log(n2), f"log_{{{n2}}}{{({-n1})}}"),
            #(log(-n1)/log(-n2), f"log_{{{-n2}}}{{({-n1})}}"),
            ]

        return exprs_temp1

    def _get_latex_str(self, expr):
        if hasattr(expr, '_repr_latex_'):
            result = f"{expr._repr_latex_().replace('$', '')}"
        else:
            result = f"{expr}"

        return result
        pass


    pass