package com.mantz_it.guitartunerlibrary;


import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;


/**
 * <h1>Wear Guitar Tuner - Vintage Needle Tuner Skin</h1>
 *
 * Module:      VintageNeedleTunerSkin.java
 * Description: This is nice skin with a vintage look and a needle. It is based on the default skin
 *
 * @author Dennis Mantz
 *
 * Copyright (C) 2014 Dennis Mantz
 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
public class VintageNeedleTunerSkin extends DefaultTunerSkin {

	private Resources resources;		// resources instance to load bitmaps
	private Bitmap scaledBackground;	// will hold the background bitmap scaled to the surface dimensions
	private Paint jewelLightPaint;
	private Paint jewelLightHousingPaint;
	private Paint brandTextPaint;
	private Paint knobPaint;
	private Paint knobIndicatorPaint;
	private Paint labelTextPaint;
	private Paint dialBackgroundPaint;
	/**
	 * constructor.
	 * @param resources		resources instance to load bitmaps
	 */
	public VintageNeedleTunerSkin(Resources resources) {
		super();
		this.resources = resources;
		sideLettersPosition = 0.45f;	// bring the side letters closer to the center
		maxAngle = 0.6f;				// also narrow the scale to fit inside the window of the background image
	}

	@Override
	public void updateWidthAndHeight(int width, int height) {
		super.updateWidthAndHeight(width, height);
		foregroundPaint.setTextSize(height * 0.15f);
		invalidPaint.setTextSize(height * 0.15f);
		highlightPaint.setTextSize(height * 0.15f);
		gradientPaint.setTextSize(height * 0.12f);
		gradientPaint.setShader(new LinearGradient(width/5, 0, width / 2, 0, Color.DKGRAY, Color.LTGRAY, Shader.TileMode.MIRROR));
		highlightPaint.setColor(Color.parseColor("#28C902"));

		jewelLightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		jewelLightPaint.setColor(Color.parseColor("#FF0000"));
		jewelLightPaint.setStyle(Paint.Style.FILL);

		jewelLightHousingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		jewelLightHousingPaint.setColor(Color.parseColor("#333333"));
		jewelLightHousingPaint.setStyle(Paint.Style.STROKE);
		jewelLightHousingPaint.setStrokeWidth(4);

		brandTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		brandTextPaint.setColor(Color.parseColor("#555555"));
		brandTextPaint.setTextSize(height * 0.08f);
		brandTextPaint.setTextAlign(Paint.Align.CENTER);
		brandTextPaint.setFakeBoldText(true);

		knobPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		knobPaint.setShader(new LinearGradient(0, height * 0.7f, 0, height * 0.9f,
				Color.parseColor("#C0C0C0"), // Dull silver top
				Color.parseColor("#656565"), // Dark silver bottom
				Shader.TileMode.CLAMP));

		knobIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		knobIndicatorPaint.setColor(Color.parseColor("#202020"));
		knobIndicatorPaint.setStyle(Paint.Style.STROKE);
		knobIndicatorPaint.setStrokeWidth(4);

		labelTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		labelTextPaint.setColor(Color.parseColor("#505050"));
		labelTextPaint.setTextSize(height * 0.06f);
		labelTextPaint.setTextAlign(Paint.Align.CENTER);

		// --- "WORN OUT" CREAM GRADIENT ---
		dialBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		dialBackgroundPaint.setStyle(Paint.Style.FILL);

		// CRASH FIX: Only create the shader if the view has a valid size.
		if (width > 0 && height > 0) {
			int centerColor = Color.parseColor("#F5F5DC"); // Clean Beige in the middle
			int edgeColor = Color.parseColor("#D2B48C");   // Darker, "Tannish" color for the edges/stains

			// A radial gradient makes the center lighter and the edges darker, like it's worn.
			dialBackgroundPaint.setShader(new android.graphics.RadialGradient(
					width / 2f,         // Center X
					height * 0.45f,     // Center Y (shifted up into the window area)
					width / 1.5f,       // Radius (large enough to look subtle)
					centerColor, edgeColor, Shader.TileMode.CLAMP
			));
		}

		loadBackground();
	}

	@Override
	public void setRound(boolean round) {
		super.setRound(round);

		// Load skin background and scale it to the surface dimensions
		loadBackground();
	}

	/**
	 * Loads the background bitmap and scales it according to the surface dimensions
	 */
	private void loadBackground() {
		if(width > 0 && height > 0) {
			if(round)
				scaledBackground = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(resources, R.drawable.vintage_tuner_skin_round), width, height, false);
			else
				scaledBackground = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(resources, R.drawable.vintage_silver_skin), width, height, false);
		}
	}

	@Override
	public void draw(Canvas c, GuitarTuner tuner) {
		// This method is called for non-animated drawing.
		// We'll just call the main draw method and tell it it's the first and only frame.
		draw(c, tuner, 0, 1);
	}

	// In VintageNeedleTunerSkin.java
// REPLACE the second, more complex draw method with this one.

// In VintageNeedleTunerSkin.java
// REPLACE the entire draw(Canvas c, GuitarTuner tuner, int frameNumber, int framesPerCycle) method with this one.

	// In VintageNeedleTunerSkin.java
// REPLACE the entire draw(Canvas c, GuitarTuner tuner, int frameNumber, int framesPerCycle) method with this one.

	@Override
	public void draw(Canvas c, GuitarTuner tuner, int frameNumber, int framesPerCycle) {

		// 1. Draw the solid black background first.
		c.drawRect(0, 0, width, height, backgroundPaint);

		// --- STEP 1: DRAW THE CREAM RECTANGLE FIRST ---
		// By drawing this before the silver bitmap, it will show through the bitmap's transparent areas.
		float dialTop = height * 0.2f;
		float dialBottom = height * 0.7f;
		float dialLeft = 0;
		float dialRight = width;
		c.drawRect(dialLeft, dialTop, dialRight, dialBottom, dialBackgroundPaint);


		// --- STEP 2: DRAW THE SILVER FACEPLATE ON TOP ---
		if(scaledBackground != null) {
			c.drawBitmap(scaledBackground, 0, 0, null);
		}


		// 2. Draw all other decorative elements on top of everything.

		// --- DRAW THE JEWEL LIGHT (NOW WITH CONDITIONAL COLOR) ---
		// Check if the tuner is in tune and set the color accordingly.
		if (tuner.isTuned()) {
			jewelLightPaint.setColor(Color.parseColor("#28C902")); // Bright Green
		} else {
			jewelLightPaint.setColor(Color.parseColor("#FF0000")); // Default Red
		}
		float jewelX = width * 0.85f;
		float jewelY = height * 0.25f;
		float jewelRadius = height * 0.05f;
		c.drawCircle(jewelX, jewelY, jewelRadius, jewelLightHousingPaint); // The housing
		c.drawCircle(jewelX, jewelY, jewelRadius, jewelLightPaint);      // The light


		// Draw the Brand Text
		c.drawText("Tune-Rite", width / 2, height * 0.2f, brandTextPaint);

		// --- Draw Decorative Knobs with Labels - 3D Silver Style ---
		float knobRadius = height * 0.08f;
		float knobY = height * 0.80f;
		float labelY = knobY + knobRadius + (height * 0.07f);

		Paint knobBasePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		knobBasePaint.setColor(Color.parseColor("#1a1a1a")); // Almost black
		knobBasePaint.setStyle(Paint.Style.FILL);

		// --- Draw the left knob ("CALIBRATE") ---
		float knob1X = width * 0.18f;
		c.drawCircle(knob1X, knobY, knobRadius + 2, knobBasePaint);
		c.drawCircle(knob1X, knobY, knobRadius, knobPaint);
		c.drawLine(knob1X, knobY - (knobRadius * 0.8f), knob1X, knobY - (knobRadius * 0.3f), knobIndicatorPaint);
		c.drawText("CALIBRATE", knob1X, labelY, labelTextPaint);

		// --- Draw the right knob ("440Hz") ---
		float knob2X = width * 0.82f;
		c.drawCircle(knob2X, knobY, knobRadius + 2, knobBasePaint);
		c.drawCircle(knob2X, knobY, knobRadius, knobPaint);
		c.save();
		c.rotate(45, knob2X, knobY);
		c.drawLine(knob2X, knobY - (knobRadius * 0.8f), knob2X, knobY - (knobRadius * 0.3f), knobIndicatorPaint);
		c.restore();
		//String concertPitchText = String.format("%.0fHz", tuner.getConcertPitch());
		//String concertPitchText = String.format("%.0fHz", 440);
		//c.drawText(concertPitchText, knob2X, labelY, labelTextPaint);


		// 3. Draw the tuner elements (needle, scale, etc.) on top of the cream window.
		drawScale(c);

		if(tuner.isValid() && tuner.getTargetFrequency() > 0) {
			float targetFrequency = tuner.getTargetFrequency();
			int targetPitchIndex = tuner.getTargetPitchIndex();

			String centerLetter = tuner.pitchLetterFromIndex(targetPitchIndex);
			Paint letterPaint = tuner.isTuned() ? highlightPaint : gradientPaint;
			drawPitchLetter(c, centerLetter, 0, 0.48f, true, letterPaint);

			float angle;
			final double TUNED_THRESHOLD_CENTS = 2.5;
			double detectedFrequency = tuner.getDetectedFrequency();
			double diffInCents = 1200 * Math.log(detectedFrequency / targetFrequency) / Math.log(2);

			if (Math.abs(diffInCents) < TUNED_THRESHOLD_CENTS) {
				angle = 0;
			} else {
				double clampedDiff = Math.max(-50.0, Math.min(50.0, diffInCents));
				angle = (float) (clampedDiff / 50.0) * maxAngle;
			}

			drawNeedle(c, angle, tuner.isTuned() ? highlightPaint : foregroundPaint);

		} else {
			drawPitchLetter(c, "---", 0, 0.48f, true, invalidPaint);
		}
	}
}
