# Copyright 3D Control Systems, Inc. All Rights Reserved 2017-2019.
# Built in San Francisco.

# This software is distributed under a commercial license for personal,
# educational, corporate or any other use.
# The software as a whole or any parts of it is prohibited for distribution or
# use without obtaining a license from 3D Control Systems, Inc.

# All software licenses are subject to the 3DPrinterOS terms of use
# (available at https://www.3dprinteros.com/terms-and-conditions/),
# and privacy policy (available at https://www.3dprinteros.com/privacy-policy/)


def get_printers_html(request):
    printers_string = ''
    for printer_interface in request.app['3dp_app'].printer_interfaces:
        printers_string += "<p>" + get_printer_profile_string(request, printer_interface) + "</p>"
        if getattr(getattr(printer_interface, 'sender', None), 'pairing_needed', False):
            printers_string += '<p><font style="color:purple">Attention! Manual pairing needed!</font></p>'
            '<p>Please press the blinking button on the control panel<br /> of your printer to confirm your network connection.</p>'
            '<p>Note: you may need to add 3DPrinterOS Client<br /> to your firewall extensions.</p>'
            '<hr>'
    if not printers_string:
        printers_string = '<p><b>No printers detected</b>\
            <br />Please do a power cycle for printers\
            <br />and then ensure your printers are connected\
            <br />to power outlet and usb cord</p>'
    return printers_string

def get_printer_error_string(printer_interface):
    error_dict = printer_interface.get_last_error_to_display('WEBUI', persist_for=6)
    if error_dict:
        level = error_dict.get('level')
        error_code_text = f"Error {error_dict['code']}: "
        if level > 39:
            color = 'maroon'
        elif level > 29:
            color = 'brown'
        else:
            color = 'black'
            error_code_text = ''
        error_message =  f'<br /><font color="{color}">{error_code_text}{error_dict["message"]}</font>'
    else:
        error_message = ''
    return error_message

def get_printer_profile_string(request, printer_interface):
    snr = printer_interface.usb_info.get('SNR', '')
    if not request.query.get('hide_rename') == 'true':
        printer_rename_link = request.app['3dp_content']['templates']['buttons']['manage_printer_button.html'] \
            .replace('class="small_button', 'title="Press here to rename this printer" class="submit_link') \
            .replace('!!!PATH!!!', 'rename_printer') \
            .replace('!!!ACTION_NAME!!!', printer_interface.printer_name) \
            .replace('!!!PRINTER_ID!!!', printer_interface.id_string)
    else:
        printer_rename_link = ''
    printer_string = '<b>' + printer_rename_link + '<br />'
    profile = getattr(printer_interface, 'printer_profile', {'alias': "", 'name':
                        f"Awaiting profile {printer_interface.usb_info['VID']}:{printer_interface.usb_info['PID']}"})
    if profile:
        if profile.get('ID_CLONE_WARNING'):
            id_clone_string = '<span title=" This printer have same USB id as another printer connection to this' \
                              'machine. Printer is working in compatibility mode.">' \
                              '<font color="maroon">&#9888</font><span> '
        else:
            id_clone_string = ''
        printer_string += id_clone_string + '<font color="black"><b>' + profile['name'] + ' </b></font><font title="Serial number">' + snr + '</font>'
    else:
        if printer_interface.show_printer_type_selector:
            printer_string += '<br><font color="maroon"><b>Printer type selection required</b></font>'
        else:
            printer_string += '<br>Processing type selection'
    printer_report = printer_interface.status_report()
    error_message = ""
    if printer_report:
        printer_string += ' - ' + get_printer_state_string(request, printer_interface) \
                                + '<br />' + get_printer_temps_string(printer_report) + '<br />'
        if not request.query.get('hide_type_select') == 'true':
            printer_string += get_printer_type_select_button(request, printer_interface)
    if not request.query.get('hide_control') == 'true':
        printer_string += get_manage_printer_button(request, printer_interface)
    error_message = get_printer_error_string(printer_interface)
    printer_string += '<br />' + error_message + '<br />'
    return printer_string + '<hr width="320px">'

def get_printer_state_string(request, printer_interface):
    printer_report = printer_interface.status_report()
    state = printer_report.get('state')
    percent = printer_report.get('percent')
    if state == 'error' or state == 'cancel':
        color = 'red'
    elif state == 'connecting' or state == 'closing':
        color = 'purple'
    elif state == 'ready' or state == 'local_mode':
        color = 'green'
    elif state == 'local_mode':
        color = 'brown'
    elif state == 'printing':
        color = 'blue'
    elif state == 'paused':
        color = 'orange'
    elif state == 'downloading':
        color = 'lightblue'
    elif state == 'bed_not_clear':
        color = 'darkgrey'
    else:
        color = 'black'
    if percent is not None and state == 'printing' or state == 'paused' or state == 'downloading':
        progress = ' | %d%% %s' % (percent, get_printing_cancel_button(request, printer_interface))
    else:
        progress = ''
    return '<font color="' + color + '">' + state + progress + '</font> '

def get_printer_temps_string(printer_report):
    temps = printer_report.get('temps')
    target_temps = printer_report.get('target_temps')
    temps_string = ''
    if temps and target_temps:
        if temps and len(temps) > 1:
            temps_string =  'First Tool: %s/%s | Heated Bed: %s/%s' %\
                            (temps[1], target_temps[1], temps[0], target_temps[0])
        if len(temps) >= 3 and len(target_temps) >= 3:
            temps_string = temps_string.replace('| H', '| Second Tool: %s/%s | H' % (temps[2], target_temps[2]))
    return temps_string

def get_printer_type_select_button(request, printer_interface):
    profile = getattr(printer_interface, 'printer_profile', None)
    if not profile:
        if printer_interface.show_printer_type_selector:
            button_name = 'Select printer type'
            printer_type_path = 'select_printer_type'
        else:
            button_name = 'Please wait...'
            printer_type_path = ''
    else:
        button_name = 'Reset printer type'
        printer_type_path = 'request_printer_type_reset'
    return request.app['3dp_content']['templates']['buttons']['manage_printer_button.html'] \
        .replace('!!!ACTION_NAME!!!', button_name)\
        .replace('!!!PRINTER_ID!!!', printer_interface.id_string)\
        .replace('!!!PATH!!!', printer_type_path)

def get_printing_cancel_button(request, printer_interface):
    printing_cancel_path = 'cancel_printing'
    return request.app['3dp_content']['templates']['buttons']['manage_printer_button.html'] \
        .replace('!!!PATH!!!', printing_cancel_path) \
        .replace('!!!ACTION_NAME!!!', 'Cancel') \
        .replace('!!!PRINTER_ID!!!', printer_interface.id_string)\
        .replace("style='display:inline;'", 'style="display:inline; width: 60px"')

def get_manage_printer_button(request, printer_interface):
    manage_printer_path = 'manage_printer'
    return request.app['3dp_content']['templates']['buttons']['manage_printer_button.html'] \
        .replace('!!!PATH!!!', manage_printer_path)\
        .replace('!!!ACTION_NAME!!!', 'Control printer')\
        .replace('!!!PRINTER_ID!!!', printer_interface.id_string)
