// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception
// Copyright (C) 2020 Jesse Chappell


#include "SonoTextButton.h"
#include "CustomLookAndFeel.h"
#include <math.h>

SonoTextButton::SonoTextButton(const String & name)
  : TextButton(name), _buttonStyle(SonoButtonStyleNormal)
{
    
}

SonoTextButton::~SonoTextButton()
{
    
}

void SonoTextButton::setButtonStyle(SonoButtonStyle style)
{
    _buttonStyle = style;
}


void SonoTextButton::drawButtonBackground(Graphics& g, bool isMouseOverButton, bool isButtonDown)
{
    Colour bgcolor = findColour (getToggleState() ? buttonOnColourId : buttonColourId);
    Colour bordcolor =  isColourSpecified(outlineColourId) ? findColour (outlineColourId) : Colour::fromFloatRGBA(0.3, 0.3, 0.3, 0.5);

    if (isButtonDown) {
        bgcolor = bgcolor.withMultipliedBrightness(1.8);
    } else if (isMouseOverButton) {
        bgcolor = bgcolor.withMultipliedBrightness(1.3);
    }
    
    g.setColour(bgcolor);
    g.fillPath(fillPath);
    
    g.setColour(bordcolor);
    g.strokePath(borderPath, PathStrokeType(1.0));
    
}


void SonoTextButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
{
    LookAndFeel& lf = getLookAndFeel();
    
    drawButtonBackground(g, isMouseOverButton, isButtonDown);

    if (auto * tetlf = dynamic_cast<CustomLookAndFeel*>(&lf)) {
        Justification just = textJustification;
        switch (_buttonStyle) {
            case SonoButtonStyleLowerLeftCorner: just = Justification::centredLeft; break;
            case SonoButtonStyleLowerRightCorner: just = Justification::centredRight; break;
            default: break;
        }
        
        tetlf->drawButtonTextWithAlignment (g, *this, isMouseOverButton, isButtonDown, just);
    }
    else {
        lf.drawButtonText (g, *this, isMouseOverButton, isButtonDown);
    }
}

bool SonoTextButton::hitTest (int x, int y)
{
    return fillPath.contains(x, y);
}


void SonoTextButton::resized()
{
    TextButton::resized();
    
    setupPath();
}

void SonoTextButton::setupPath() {

    float borderOffset = 0.5; // _borderWidth*1.5f;
    float width = getWidth();
    float height = getHeight();
    fillPath.clear();
    borderPath.clear();
    
 
    if (_buttonStyle == SonoButtonStyleTop) {
        fillPath.startNewSubPath(borderOffset, borderOffset);
        fillPath.quadraticTo(width/2.0, height-borderOffset, width - borderOffset, borderOffset);
        fillPath.lineTo(borderOffset, borderOffset);

        borderPath.startNewSubPath(borderOffset, borderOffset);
        borderPath.quadraticTo(width/2.0, height-borderOffset, width - borderOffset, borderOffset);

        //[fillPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[fillPath addQuadCurveToPoint:CGPointMake(width - borderOffset, borderOffset) controlPoint:CGPointMake(width/2.0, height-borderOffset) ];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        
        //[borderPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[borderPath addQuadCurveToPoint:CGPointMake(width - borderOffset, borderOffset) controlPoint:CGPointMake(width/2.0, height-borderOffset) ];


    }
    else if (_buttonStyle == SonoButtonStyleBottom) {
        // H /2 + W^2 / 8H
        float maxdim =  jmax(width, height);
        float radius = circleRadius > 0.0f ? circleRadius :  height * 0.5 + (width*width)/(8.0f * height);
        float startAng = atan2(height - radius, maxdim/2 - width);
        float endAng = atan2(height - radius, width - maxdim/2);

        startAng += M_PI_2;
        endAng += M_PI_2;
        
        DBG("Start ang " << radiansToDegrees(startAng) << " end " << radiansToDegrees(endAng) << " h: " << height << "  rad: " << radius);
        
        fillPath.startNewSubPath(borderOffset, height - borderOffset);
        fillPath.addCentredArc(maxdim/2, radius, radius, radius, 0.0f, startAng, endAng);
        fillPath.lineTo(borderOffset, height - borderOffset);

        borderPath.startNewSubPath(borderOffset, height - borderOffset);
        borderPath.addCentredArc(maxdim/2, radius, radius, radius, 0.0f, startAng, endAng);
        borderPath.lineTo(borderOffset, height - borderOffset);

        
        //[fillPath moveToPoint:CGPointMake(borderOffset, height - borderOffset)];
        //[fillPath addArcWithCenter:CGPointMake(maxdim/2, radius) radius:radius startAngle:startAng endAngle:endAng clockwise:YES];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(borderOffset, height -borderOffset)];
        //[borderPath addArcWithCenter:CGPointMake(maxdim/2, radius) radius:radius startAngle:startAng endAngle:endAng clockwise:YES];
        //[borderPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
    }
    else if (_buttonStyle == SonoButtonStyleLeft) {

        fillPath.startNewSubPath(borderOffset, borderOffset);
        fillPath.quadraticTo(width - borderOffset, borderOffset, width - borderOffset, height/2);
        fillPath.quadraticTo(width - borderOffset, height-borderOffset, borderOffset, height-borderOffset);
        fillPath.lineTo(borderOffset, borderOffset);

        borderPath.startNewSubPath(borderOffset, borderOffset);
        borderPath.quadraticTo(width - borderOffset, borderOffset, width - borderOffset, height/2);
        borderPath.quadraticTo(width - borderOffset, height-borderOffset, borderOffset, height-borderOffset);
        
        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[fillPath addQuadCurveToPoint:CGPointMake(width - borderOffset, height/2) controlPoint:CGPointMake(width - borderOffset , borderOffset) ];
        //[fillPath addQuadCurveToPoint:CGPointMake(borderOffset, height-borderOffset) controlPoint:CGPointMake(width - borderOffset , height-borderOffset) ];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[borderPath addQuadCurveToPoint:CGPointMake(width - borderOffset, height/2) controlPoint:CGPointMake(width - borderOffset , borderOffset) ];
        //[borderPath addQuadCurveToPoint:CGPointMake(borderOffset, height-borderOffset) controlPoint:CGPointMake(width - borderOffset , height-borderOffset) ];
    }
    else if (_buttonStyle == SonoButtonStyleRight) {

        fillPath.startNewSubPath(width - borderOffset, borderOffset);
        fillPath.quadraticTo(borderOffset, borderOffset, borderOffset, height/2);
        fillPath.quadraticTo(borderOffset, height-borderOffset, width - borderOffset, height-borderOffset);
        fillPath.lineTo(width - borderOffset, borderOffset);
        
        borderPath.startNewSubPath(width - borderOffset, borderOffset);
        borderPath.quadraticTo(borderOffset, borderOffset, borderOffset, height/2);
        borderPath.quadraticTo(borderOffset, height-borderOffset, width - borderOffset, height-borderOffset);

        
        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(width - borderOffset, borderOffset)];
        //[fillPath addQuadCurveToPoint:CGPointMake(borderOffset, height/2) controlPoint:CGPointMake(borderOffset, borderOffset) ];
        //[fillPath addQuadCurveToPoint:CGPointMake(width - borderOffset, height - borderOffset) controlPoint:CGPointMake(borderOffset, height - borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(width - borderOffset, borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(width -borderOffset, borderOffset)];
        //[borderPath addQuadCurveToPoint:CGPointMake(borderOffset, height/2) controlPoint:CGPointMake(borderOffset, borderOffset) ];
        //[borderPath addQuadCurveToPoint:CGPointMake(width - borderOffset, height - borderOffset) controlPoint:CGPointMake(borderOffset, height - borderOffset)];
        
    }
    else if (_buttonStyle == SonoButtonStyleUpperLeftCorner) {

        fillPath.startNewSubPath(borderOffset, borderOffset);
        fillPath.lineTo(width - borderOffset, borderOffset);
        fillPath.quadraticTo(width - borderOffset, height - borderOffset, borderOffset, height - borderOffset);
        fillPath.lineTo(borderOffset, borderOffset);

        borderPath.startNewSubPath(width - borderOffset, borderOffset);
        borderPath.quadraticTo(width - borderOffset, height - borderOffset, borderOffset, height - borderOffset);

        
        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(width-borderOffset, borderOffset)];
        //[fillPath addQuadCurveToPoint:CGPointMake(borderOffset, height-borderOffset) controlPoint:CGPointMake(width-borderOffset, height-borderOffset) ];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(width-borderOffset, borderOffset)];
        //[borderPath addQuadCurveToPoint:CGPointMake(borderOffset, height-borderOffset) controlPoint:CGPointMake(width-borderOffset, height-borderOffset) ];
        
    }
    else if (_buttonStyle == SonoButtonStyleUpperRightCorner) {

        fillPath.startNewSubPath(width - borderOffset, borderOffset);
        fillPath.lineTo(width - borderOffset, height - borderOffset);
        fillPath.quadraticTo(borderOffset, height - borderOffset, borderOffset, borderOffset);
        fillPath.lineTo(width - borderOffset, borderOffset);
        
        borderPath.startNewSubPath(width - borderOffset, height - borderOffset);
        borderPath.quadraticTo(borderOffset, height - borderOffset, borderOffset, borderOffset);

        
        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(width - borderOffset, borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(width - borderOffset, height - borderOffset)];
        //[fillPath addQuadCurveToPoint:CGPointMake(borderOffset, borderOffset) controlPoint:CGPointMake(borderOffset, height-borderOffset) ];
        //[fillPath addLineToPoint:CGPointMake(width - borderOffset, borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(width - borderOffset, height - borderOffset)];
        //[borderPath addQuadCurveToPoint:CGPointMake(borderOffset, borderOffset) controlPoint:CGPointMake(borderOffset, height-borderOffset) ];
        
    }
    else if (_buttonStyle == SonoButtonStyleLowerLeftCorner) {

        fillPath.startNewSubPath(borderOffset, height - borderOffset);
        fillPath.lineTo(borderOffset, borderOffset);
        fillPath.quadraticTo(width-borderOffset, borderOffset, width-borderOffset, height-borderOffset);
        fillPath.lineTo(borderOffset, height-borderOffset);

        borderPath.startNewSubPath(borderOffset, borderOffset);
        borderPath.quadraticTo(width-borderOffset, borderOffset, width-borderOffset, height-borderOffset);

        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(borderOffset, height-borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        //[fillPath addQuadCurveToPoint:CGPointMake(width-borderOffset, height-borderOffset) controlPoint:CGPointMake(width-borderOffset, borderOffset) ];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, height-borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[borderPath addQuadCurveToPoint:CGPointMake(width-borderOffset, height-borderOffset) controlPoint:CGPointMake(width-borderOffset, borderOffset) ];
    }
    else if (_buttonStyle == SonoButtonStyleLowerRightCorner) {

        fillPath.startNewSubPath(width-borderOffset, height - borderOffset);
        fillPath.lineTo(borderOffset, height-borderOffset);
        fillPath.quadraticTo(borderOffset, borderOffset, width-borderOffset, borderOffset);
        fillPath.lineTo(width - borderOffset, height-borderOffset);
        
        borderPath.startNewSubPath(borderOffset, height - borderOffset);
        borderPath.quadraticTo(borderOffset, borderOffset, width-borderOffset, borderOffset);

        
        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(width-borderOffset, height-borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, height-borderOffset)];
        //[fillPath addQuadCurveToPoint:CGPointMake(width-borderOffset, borderOffset) controlPoint:CGPointMake(borderOffset, borderOffset) ];
        //[fillPath addLineToPoint:CGPointMake(width-borderOffset, height-borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(borderOffset, height-borderOffset)];
        //[borderPath addQuadCurveToPoint:CGPointMake(width-borderOffset, borderOffset) controlPoint:CGPointMake(borderOffset, borderOffset) ];
    }
    else if (_buttonStyle == SonoButtonStyleLowerRightCornerRound) {
        float maxdim =  jmax(width*2, height);
        // H /2 + W^2 / 8H (but double the width here)
        float radius = circleRadius > 0.0f ? circleRadius : height * 0.5 + (width*width*4.0)/(8.0f * height);
        float startAng = atan2(height - radius, maxdim/2 - width*2);
        float endAng = atan2(height - radius, width - maxdim/2) ;
        
        startAng += M_PI_2;
        endAng += M_PI_2;

        fillPath.startNewSubPath(borderOffset, height - borderOffset);
        fillPath.addCentredArc(maxdim/2, radius, radius, radius, 0.0f, startAng, endAng);
        fillPath.lineTo(width - borderOffset, height - borderOffset);
        fillPath.lineTo(borderOffset, height - borderOffset);

        borderPath.startNewSubPath(borderOffset, height - borderOffset);
        borderPath.addCentredArc(maxdim/2, radius, radius, radius, 0.0f, startAng, endAng);
        borderPath.lineTo(width - borderOffset, height - borderOffset);
        borderPath.lineTo(borderOffset, height - borderOffset);

        
        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(borderOffset, height - borderOffset)];
        //[fillPath addArcWithCenter:CGPointMake(maxdim/2, radius) radius:radius startAngle:startAng endAngle:endAng clockwise:YES];
        //[fillPath addLineToPoint:CGPointMake(width - borderOffset, height - borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(borderOffset, height -borderOffset)];
        //[borderPath addArcWithCenter:CGPointMake(maxdim/2, radius) radius:radius startAngle:startAng endAngle:endAng clockwise:YES];
        //[borderPath addLineToPoint:CGPointMake(width - borderOffset, height - borderOffset)];
        //[borderPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
    }
    else if (_buttonStyle == SonoButtonStyleLowerLeftCornerRound) {
        float maxdim =  jmax(width*2, height);
        // H /2 + W^2 / 8H (but double the width here)
        float radius = circleRadius > 0.0f ? circleRadius : height * 0.5 + (width*width*4.0)/(8.0f * height);
        float startAng = atan2(height - radius, width - maxdim/2) ;
        float endAng = atan2(height - radius, width*2 - maxdim/2);
        startAng += M_PI_2;
        endAng += M_PI_2;

        fillPath.startNewSubPath(borderOffset, height - borderOffset);
        fillPath.lineTo(borderOffset, borderOffset);
        fillPath.addCentredArc(maxdim/2, radius, radius, radius, 0.0f, startAng, endAng);
        fillPath.lineTo(borderOffset, height - borderOffset);

        borderPath.startNewSubPath(borderOffset, height - borderOffset);
        borderPath.lineTo(borderOffset, borderOffset);
        borderPath.addCentredArc(maxdim/2, radius, radius, radius, 0.0f, startAng, endAng);
        borderPath.lineTo(borderOffset, height - borderOffset);
        
        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(borderOffset, height - borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        //[fillPath addArcWithCenter:CGPointMake(maxdim/2 - width, radius) radius:radius startAngle:startAng endAngle:endAng clockwise:YES];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(borderOffset, height -borderOffset)];
        //[borderPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        //[borderPath addArcWithCenter:CGPointMake(maxdim/2 - width, radius) radius:radius startAngle:startAng endAngle:endAng clockwise:YES];
        //[borderPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
    }
    else if (_buttonStyle == SonoButtonStyleUpperRightCornerRound) {
        float maxdim =  jmax(width*2, height);
        // H /2 + W^2 / 8H (but double the width here)
        float radius = circleRadius > 0.0f ? circleRadius : height * 0.5 + (width*width*4.0)/(8.0f * height);
        float startAng = atan2(radius - height, maxdim/2 - width*2);
        float endAng = atan2(radius - height , width - maxdim/2) ;
        startAng += M_PI_2;
        endAng += M_PI_2;

        DBG("URC Start ang " << radiansToDegrees(startAng) << " end " << radiansToDegrees(endAng) << " h: " << height << "  rad: " << radius);

        fillPath.startNewSubPath(borderOffset, borderOffset);
        fillPath.addCentredArc(maxdim/2, height-radius, radius, radius, 0.0f, startAng, endAng);
        fillPath.lineTo(width - borderOffset, borderOffset);
        fillPath.lineTo(borderOffset, borderOffset);

        borderPath.startNewSubPath(borderOffset, borderOffset);
        borderPath.addCentredArc(maxdim/2, height-radius, radius, radius, 0.0f, startAng, endAng);
        borderPath.startNewSubPath(width - borderOffset, borderOffset);
        borderPath.lineTo(borderOffset, borderOffset);

        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[fillPath addArcWithCenter:CGPointMake(maxdim/2, height -radius) radius:radius startAngle:startAng endAngle:endAng clockwise:NO];
        //[fillPath addLineToPoint:CGPointMake(width - borderOffset, borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        //[borderPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[borderPath addArcWithCenter:CGPointMake(maxdim/2, height -radius) radius:radius startAngle:startAng endAngle:endAng clockwise:NO];
        //[borderPath addLineToPoint:CGPointMake(width - borderOffset, borderOffset)];
        //[borderPath moveToPoint:CGPointMake(width - borderOffset, borderOffset)];
        //[borderPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
    }
    else if (_buttonStyle == SonoButtonStyleUpperLeftCornerRound) {
        float maxdim =  jmax(width*2, height);
        // H /2 + W^2 / 8H (but double the width here)
        float radius = circleRadius > 0.0f ? circleRadius : height * 0.5 + (width*width*4.0)/(8.0f * height);
        float startAng = atan2(radius - height, width - maxdim/2) ;
        float endAng = atan2(radius-height, width*2 - maxdim/2);
        startAng += M_PI_2;
        endAng += M_PI_2;

        DBG("URC Start ang " << radiansToDegrees(startAng) << " end " << radiansToDegrees(endAng) << " h: " << height << "  rad: " << radius);

        
        fillPath.startNewSubPath(borderOffset, borderOffset);
        fillPath.lineTo(borderOffset, height - borderOffset);
        fillPath.addCentredArc(maxdim/2 - width, height-radius, radius, radius, 0.0f, startAng, endAng);
        fillPath.lineTo(borderOffset, borderOffset);

        borderPath.startNewSubPath(borderOffset, height - borderOffset);
        borderPath.lineTo(borderOffset, height - borderOffset);
        borderPath.addCentredArc(maxdim/2 - width, height-radius, radius, radius, 0.0f, startAng, endAng);
        borderPath.lineTo(borderOffset, borderOffset);

        //fillPath = [UIBezierPath bezierPath];
        //[fillPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
        ////[fillPath moveToPoint:CGPointMake(borderOffset, height - borderOffset)];
        //[fillPath addArcWithCenter:CGPointMake(maxdim/2 - width, height -radius) radius:radius startAngle:startAng endAngle:endAng clockwise:NO];
        //[fillPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
        
        //borderPath = [UIBezierPath bezierPath];
        ////[borderPath moveToPoint:CGPointMake(borderOffset, borderOffset)];
        ////[borderPath addLineToPoint:CGPointMake(borderOffset, height - borderOffset)];
        //[borderPath moveToPoint:CGPointMake(borderOffset, height - borderOffset)];
        //[borderPath addArcWithCenter:CGPointMake(maxdim/2 - width, height -radius) radius:radius startAngle:startAng endAngle:endAng clockwise:NO];
        //[borderPath addLineToPoint:CGPointMake(borderOffset, borderOffset)];
    }
    else
    {
        auto bounds = getLocalBounds().toFloat().reduced(borderOffset);
        fillPath.addRoundedRectangle(bounds, cornerRadius);
        borderPath.addRoundedRectangle(bounds, cornerRadius);
    }

    
}
