#!/usr/bin/env python3
# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.


"""Generates image of Totoro from the Miyazaki's film My Neighbor Totoro."""

import os
import sys

from openeye import oechem, oedepict


def main() -> int:
    """Depict Totoro."""
    image_width, image_height = 200, 200
    image = oedepict.OEImage(image_width, image_height)

    white_pen = oedepict.OEPen(oechem.OEWhite, oechem.OEWhite, oedepict.OEFill_On, 1.0)
    black_pen = oedepict.OEPen(oechem.OEBlack, oechem.OEBlack, oedepict.OEFill_On, 1.0)
    light_grey_pen = oedepict.OEPen(
        oechem.OEColor(170, 160, 160),
        oechem.OEColor(170, 160, 160),
        oedepict.OEFill_On,
        1.0,
    )
    med_grey_pen = oedepict.OEPen(
        oechem.OEColor(100, 90, 90),
        oechem.OEColor(100, 90, 90),
        oedepict.OEFill_On,
        4.0,
    )

    center = oedepict.OE2DPoint(100, 120)

    # head

    to = center + oedepict.OE2DPoint(0, -45)
    rt = center + oedepict.OE2DPoint(+80, +20)
    lf = center + oedepict.OE2DPoint(-80, +20)

    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(+20, -15),
        rt + oedepict.OE2DPoint(+15, -20),
        rt,
        light_grey_pen,
    )
    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(-20, -15),
        lf + oedepict.OE2DPoint(-15, -20),
        lf,
        light_grey_pen,
    )
    image.DrawTriangle(to, rt, lf, light_grey_pen)
    image.DrawCircle(to, 3, light_grey_pen)

    _draw_ellipse(image, center + oedepict.OE2DPoint(0, +20), 210, 30, light_grey_pen)

    # ears

    _draw_ellipse(image, center + oedepict.OE2DPoint(-40, -50), 40, 80, light_grey_pen)
    _draw_ellipse(image, center + oedepict.OE2DPoint(+40, -50), 40, 80, light_grey_pen)

    # eyes

    image.DrawCircle(center + oedepict.OE2DPoint(-40, -10), 10, white_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(-42, -15), 4, black_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(-43, -16), 1, white_pen)

    image.DrawCircle(center + oedepict.OE2DPoint(+40, -10), 10, white_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(+38, -15), 4, black_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(+38, -16), 1, white_pen)

    # nose

    image.DrawCircle(center + oedepict.OE2DPoint(0, -10), 2, med_grey_pen)
    image.DrawArc(center + oedepict.OE2DPoint(0, 20), 345, 15, 31, med_grey_pen)

    # whiskers

    image.DrawLine(
        center + oedepict.OE2DPoint(+55, 0),
        center + oedepict.OE2DPoint(+90, -15),
        med_grey_pen,
    )
    image.DrawLine(
        center + oedepict.OE2DPoint(-55, 0),
        center + oedepict.OE2DPoint(-90, -15),
        med_grey_pen,
    )

    image.DrawLine(
        center + oedepict.OE2DPoint(+60, 5),
        center + oedepict.OE2DPoint(+95, +5),
        med_grey_pen,
    )
    image.DrawLine(
        center + oedepict.OE2DPoint(-60, 5),
        center + oedepict.OE2DPoint(-95, +5),
        med_grey_pen,
    )

    image.DrawLine(
        center + oedepict.OE2DPoint(+55, 10),
        center + oedepict.OE2DPoint(+95, +20),
        med_grey_pen,
    )
    image.DrawLine(
        center + oedepict.OE2DPoint(-55, 10),
        center + oedepict.OE2DPoint(-95, +20),
        med_grey_pen,
    )

    # add OEDepict TK watermark

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        10,
        oedepict.OEAlignment_Right,
        oechem.OELightGrey,
    )
    text = "Generated by OEDepict TK"
    image.DrawText(
        oedepict.OE2DPoint(image_width - 5.0, image_height - 5.0), text, font
    )

    # write image

    oedepict.OEWriteImage("totoro.svg", image)

    return os.EX_OK


def _draw_ellipse(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    width: float,
    height: float,
    pen: oedepict.OEPen,
) -> None:
    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        pen,
    )

    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        pen,
    )


if __name__ == "__main__":
    sys.exit(main())
