package com.mantz_it.guitartunerlibrary;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;

public class TunerSkinVintagePro extends TunerSkin {

    // --- Paints ---
    private Paint backgroundPaint;
    private Paint meterCasePaint;
    private Paint meterFacePaint;
    private Paint meterArchPaint;
    private Paint textPaint;
    private Paint needlePaint;
    private Paint inTunePaint;
    private Paint lightOffPaint;
    private Paint lightOnPaint;
    private Paint markingsPaint;
    private Paint logoPaint;

    // --- Coordinates, Dimensions, and Paths ---
    private RectF meterCaseRect;
    private RectF meterFaceRect;
    private Path meterArchPath;
    private Path textArcPath;
    private float centerX, centerY;
    private float needlePivotX, needlePivotY;
    private float needleLength;
    private float lightCenterX, lightCenterY, lightRadius;
    private Paint accentMarkingsPaint;
    public TunerSkinVintagePro() {
        super();
        init();
    }

    public void init() {
        // --- Initialize all Paint objects here ---

        backgroundPaint = new Paint();
        backgroundPaint.setColor(Color.parseColor("#1C1C1C"));
        backgroundPaint.setStyle(Paint.Style.FILL);

        meterCasePaint = new Paint();
        meterCasePaint.setAntiAlias(true);

        meterFacePaint = new Paint();
        meterFacePaint.setColor(Color.parseColor("#DDCDBA"));
        meterFacePaint.setAntiAlias(true);

        meterArchPaint = new Paint();
        meterArchPaint.setColor(Color.BLACK);
        meterArchPaint.setStyle(Paint.Style.STROKE);
        meterArchPaint.setStrokeWidth(8);
        meterArchPaint.setAntiAlias(true);

        textPaint = new Paint();
        textPaint.setColor(Color.BLACK);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setAntiAlias(true);
        textPaint.setFakeBoldText(true);

        markingsPaint = new Paint();
        markingsPaint.setColor(Color.parseColor("#333333"));
        markingsPaint.setTextAlign(Paint.Align.LEFT); // Use LEFT align for drawTextOnPath
        markingsPaint.setAntiAlias(true);
        markingsPaint.setTextSize(40);

        // In init()

        logoPaint = new Paint();
        logoPaint.setColor(Color.parseColor("#4A4A4A"));
        logoPaint.setAntiAlias(true);
        logoPaint.setTextAlign(Paint.Align.CENTER);
        logoPaint.setTextSize(55);
        logoPaint.setTypeface(Typeface.create(Typeface.SERIF, Typeface.ITALIC)); // Add this line

        accentMarkingsPaint = new Paint();
        accentMarkingsPaint.setColor(Color.parseColor("#E53935")); // A nice red color
        accentMarkingsPaint.setTextAlign(Paint.Align.LEFT);
        accentMarkingsPaint.setAntiAlias(true);
        accentMarkingsPaint.setTextSize(40);
        accentMarkingsPaint.setFakeBoldText(true);


        needlePaint = new Paint();
        needlePaint.setColor(Color.BLACK);
        needlePaint.setStrokeWidth(6);
        needlePaint.setStrokeCap(Paint.Cap.ROUND);
        needlePaint.setAntiAlias(true);

        inTunePaint = new Paint();
        inTunePaint.setColor(Color.parseColor("#E53935"));
        inTunePaint.setStrokeWidth(8);
        inTunePaint.setStrokeCap(Paint.Cap.ROUND);
        inTunePaint.setAntiAlias(true);

        lightOffPaint = new Paint();
        lightOffPaint.setColor(Color.parseColor("#4C1A1A"));
        lightOffPaint.setAntiAlias(true);

        lightOnPaint = new Paint();
        lightOnPaint.setAntiAlias(true);
    }

    @Override
    public void updateWidthAndHeight(int width, int height) {
        super.updateWidthAndHeight(width, height);
        if (width == 0 || height == 0) {
            return;
        }
        this.centerX = width / 2f;
        this.centerY = height / 2f;

        // --- Define the main meter case ---
        float caseWidth = width * 0.9f;
        float caseHeight = height * 0.7f;
        float caseLeft = (width - caseWidth) / 2;
        float caseTop = (height - caseHeight) / 2;
        meterCaseRect = new RectF(caseLeft, caseTop, caseLeft + caseWidth, caseTop + caseHeight);

        Shader caseGradient = new LinearGradient(caseLeft, caseTop, caseLeft + caseWidth, caseTop + caseHeight,
                Color.parseColor("#F5EEDC"), Color.parseColor("#D4C4A8"), Shader.TileMode.CLAMP);
        meterCasePaint.setShader(caseGradient);

        // --- Define the arched window ---
        float faceLeft = meterCaseRect.left + meterCaseRect.width() * 0.08f;
        float faceRight = meterCaseRect.right - meterCaseRect.width() * 0.08f;
        float faceBottom = meterCaseRect.bottom - meterCaseRect.height() * 0.25f;
        float faceTop = meterCaseRect.top + meterCaseRect.height() * 0.08f;
        meterFaceRect = new RectF(faceLeft, faceTop, faceRight, faceBottom);

        // --- Create the Path for the window shape ---
        // In updateWidthAndHeight()

        // --- Create the Path for the window shape ---
        meterArchPath = new Path();
        RectF arcBounds = new RectF(faceLeft, faceTop, faceRight, faceBottom);
        // 1. Start at the bottom-left corner
        meterArchPath.moveTo(faceLeft, faceBottom);
        // 2. Draw the arc over the top. arcTo will automatically add the left vertical line.
        meterArchPath.arcTo(arcBounds, 180, 180, false);
        // 3. Draw the right vertical line down to the bottom
        meterArchPath.lineTo(faceRight, faceBottom);
        // 4. Close the path, which draws the final, perfectly horizontal bottom line
        meterArchPath.close();
        // --- Create a separate, clean arc path for the text to follow ---
        textArcPath = new Path();
        // In updateWidthAndHeight()

        // In updateWidthAndHeight()

        RectF textArcBounds = new RectF(
                meterFaceRect.left - meterFaceRect.width() * 0.05f, // Widen by a smaller amount
                meterFaceRect.top,
                meterFaceRect.right + meterFaceRect.width() * 0.05f, // Widen by a smaller amount
                meterFaceRect.bottom
        );
        textArcPath.addArc(textArcBounds, 180, 180);

        // --- Define needle and light properties ---
        needlePivotX = centerX;
        needlePivotY = faceBottom;
        needleLength = meterFaceRect.height() * 0.8f;
        lightRadius = width * 0.03f;
        lightCenterX = meterCaseRect.right - lightRadius * 2.5f;
        lightCenterY = meterCaseRect.top + lightRadius * 2.5f;
    }
// Add this method at the end of your class
    /**
     * Draws text by distributing its characters evenly across a specified length of a path.
     * @param canvas The canvas to draw on.
     * @param text The text to draw.
     * @param path The path to follow.
     * @param startOffset The distance from the beginning of the path to start the distribution.
     * @param totalWidth The total width over which to distribute the characters.
     * @param vOffset The vertical distance from the path.
     * @param paint The paint to use.
     */
    private void drawTextDistributed(Canvas canvas, String text, Path path, float startOffset, float totalWidth, float vOffset, Paint paint) {
        if (text.length() < 2) {
            // Not enough characters to distribute, just draw it centered in the space
            float textWidth = paint.measureText(text);
            canvas.drawTextOnPath(text, path, startOffset + (totalWidth - textWidth) / 2, vOffset, paint);
            return;
        }

        // Calculate the space between the start of each letter
        float spacing = totalWidth / (text.length() - 1);
        float currentOffset = startOffset;

        for (char c : text.toCharArray()) {
            String character = String.valueOf(c);
            // Center each individual character over its target position
            float charWidth = paint.measureText(character);
            canvas.drawTextOnPath(character, path, currentOffset - (charWidth / 2), vOffset, paint);
            currentOffset += spacing;
        }
    }
    @Override
    public void draw(Canvas canvas, GuitarTuner tuner) {
        if (meterCaseRect == null) {
            return;
        }

        // 1. Background and Meter Case
        canvas.drawPaint(backgroundPaint);
        canvas.drawRoundRect(meterCaseRect, 20, 20, meterCasePaint);

        // 2. Meter Face
        canvas.drawPath(meterArchPath, meterFacePaint);

        // 3. Meter Markings
        // In draw()

        // 3. Meter Markings
        // 3. Meter Markings
        if (textArcPath != null) {
            markingsPaint.setTextSize(meterFaceRect.height() * 0.15f);
            markingsPaint.setFakeBoldText(true);
            markingsPaint.setLetterSpacing(0f); // We are handling spacing manually now.

            PathMeasure pm = new PathMeasure(textArcPath, false);
            float textPathLength = pm.getLength();
            float vOffset = markingsPaint.getTextSize() * 2.5f;

            // --- Draw "NORMAL" distributed across the center 50% of the arc ---
            float distributionWidth = textPathLength * 0.5f; // Use 50% of the arc's length
            float startOffset = (textPathLength - distributionWidth) / 2; // Start at the 25% mark
            drawTextDistributed(canvas, "NORMAL", textArcPath, startOffset, distributionWidth, vOffset, markingsPaint);

            // --- Draw "+" and "-" ---
            // In draw()

            // In draw()

            // --- Draw "+" and "-" ---
            // First, update the accent paint size to match the markings paint
            accentMarkingsPaint.setTextSize(markingsPaint.getTextSize());

            float minusTextWidth = accentMarkingsPaint.measureText("-");
            float hOffsetMinus = textPathLength * 0.08f - minusTextWidth / 2; // Position at 8%
            canvas.drawTextOnPath("-", textArcPath, hOffsetMinus, vOffset, accentMarkingsPaint);

            float plusTextWidth = accentMarkingsPaint.measureText("+");
            float hOffsetPlus = textPathLength * 0.92f - plusTextWidth / 2; // Position at 92%
            canvas.drawTextOnPath("+", textArcPath, hOffsetPlus, vOffset, accentMarkingsPaint);


            // --- Draw Center Tick Mark ---
            float tickYStart = meterFaceRect.top + meterFaceRect.height() * 0.05f;
            float tickYEnd = tickYStart + meterFaceRect.height() * 0.15f;
            canvas.drawLine(centerX, tickYStart, centerX, tickYEnd, markingsPaint);
        }

        // 4. "Silvertone" Logo
        logoPaint.setTextSize(meterFaceRect.height() * 0.22f);
        canvas.drawText("Silvertone", centerX, needlePivotY - logoPaint.getTextSize() * 0.5f, logoPaint);

        // 5. Window Outline (drawn on top of everything inside)
        canvas.drawPath(meterArchPath, meterArchPaint);

        // 6. Note Name
        if (tuner.isValid()) {
            textPaint.setTextSize(meterCaseRect.height() * 0.15f);
            String noteName = tuner.pitchLetterFromIndex(tuner.getTargetPitchIndex());
            canvas.drawText(noteName, centerX, meterCaseRect.bottom - meterCaseRect.height() * 0.05f, textPaint);
        }

        // 7. Needle
        if (tuner.isValid()) {
            float cents = (float) (1200 * Math.log(tuner.getDetectedFrequency() / tuner.getTargetFrequency()) / Math.log(2));
            cents = Math.max(-50.0f, Math.min(50.0f, cents));
            float rotationAngle = (cents / 50.0f) * 60.0f;

            canvas.save();
            canvas.rotate(rotationAngle, needlePivotX, needlePivotY);
            Paint currentNeedlePaint = tuner.isTuned() ? inTunePaint : needlePaint;
            canvas.drawLine(needlePivotX, needlePivotY, needlePivotX, needlePivotY - needleLength, currentNeedlePaint);
            canvas.restore();
        }

        // 8. Needle Pivot and Power Light
        canvas.drawCircle(needlePivotX, needlePivotY, 15, meterArchPaint);
        if (lightRadius > 0) {
            canvas.drawCircle(lightCenterX, lightCenterY, lightRadius, lightOffPaint);
            if (tuner.isValid()) {
                Shader lightGradient = new RadialGradient(lightCenterX, lightCenterY, lightRadius,
                        Color.parseColor("#FF8A80"), Color.parseColor("#E53935"), Shader.TileMode.CLAMP);
                lightOnPaint.setShader(lightGradient);
                canvas.drawCircle(lightCenterX, lightCenterY, lightRadius, lightOnPaint);
            }
        }
    }
}