<?php
/**
 * Main QRcdr Functions class
 *
 * @category  PHP
 * @package   QrCdr
 * @author    Nicola Franchini <info@veno.it>
 * @link      http://veno.es/qrcdr/
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class QRcdrFn {
	/**
	 * Holds an instance of the object
	 *
	 * @var QRcdrFn|null
	 */
	protected static $instance = null;

	/**
	 * Returns the running object
	 *
	 * @return QRcdrFn
	 */
	public static function getInstance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Validate URL
	 *
	 * @param string $url url to encode.
	 *
	 * @return string|false validated url or false
	 */
	public function validateUrl( $url ) {
		if ( $url ) {
			$trimmed_url = trim( $url );
			if ( strlen( $trimmed_url ) >= 2 ) {
				$url = 0 !== strpos( $trimmed_url, 'http' ) ? 'http://' . $trimmed_url : $trimmed_url;
				return urldecode( $url );
			}
		}
		return false;
	}

	/**
	 * Get config value
	 *
	 * @param string $key     key to search.
	 * @param mixed  $default default value.
	 *
	 * @return mixed config value
	 */
	public function getConfig( $key, $default = false ) {
		return qrcdr_settings()->get_option( $key, $default );
	}

	/**
	 * Delete old files
	 *
	 * @param string $dir the dir to scan.
	 * @param int    $age files lifetime.
	 * @param string $ext file extension: svg, png.
	 */
	public function deleteOldFiles( $dir = 'qrcodes/', $age = 3600, $ext = 'png' ) {
		if ( file_exists( $dir ) ) {
			$ext          = strlen( $ext ) ? '.' . $ext : '';
			$now          = time();
			$search_files = glob( $dir . '*' . $ext );

			foreach ( $search_files as $file ) {
				$file_last_modified = filemtime( $file );
				$life               = $now - $file_last_modified;
				if ( $life > $age ) {
					wp_delete_file( $file );
				}
			}
		}
	}

	/**
	 * Convert hex color
	 *
	 * @param string $color_code    color to convert.
	 * @param string $default_color default color.
	 *
	 * @return int converted color
	 */
	public function hexdecColor( $color_code, $default_color = '#000000' ) {
		// If user accidentally passed along the # sign, strip it off.
		$color_code = ltrim( $color_code, '#' );

		$color_code = strlen( $color_code ) > 6 ? substr( $color_code, 0, 6 ) : $color_code;
		$color_code = strlen( $color_code ) > 3 && strlen( $color_code ) < 6 ? substr( $color_code, 0, 3 ) : $color_code;

		if ( ctype_xdigit( $color_code ) ) {
			$converted = hexdec( str_replace( '#', '0x', $color_code ) );
		} else {
			$converted = hexdec( str_replace( '#', '0x', $default_color ) );
		}
		return $converted;
	}

	/**
	 * Increases or decreases the brightness of a color by a percentage of the current brightness.
	 *
	 * @param string $get_hex_code   Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`.
	 * @param float  $adjust_percent A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
	 *
	 * @return string
	 */
	public function adjustBrightness( $get_hex_code, $adjust_percent ) {
		$hex_code = ltrim( $get_hex_code, '#' );

		if ( 3 === strlen( $hex_code ) ) {
			$hex_code = $hex_code[0] . $hex_code[0] . $hex_code[1] . $hex_code[1] . $hex_code[2] . $hex_code[2];
		}

		$hex_code = array_map( 'hexdec', str_split( $hex_code, 2 ) );

		foreach ( $hex_code as &$color ) {
			$adjustable_limit = $adjust_percent < 0 ? $color : 255 - $color;
			$adjust_amount    = ceil( $adjustable_limit * $adjust_percent );

			$color = str_pad( dechex( $color + $adjust_amount ), 2, '0', STR_PAD_LEFT );
		}
		return '#' . implode( $hex_code );
	}

	/**
	 * Convert color hex to an RGB array.
	 *
	 * @param string $html_code The hex color to convert.
	 * @return array An associative array with 'r', 'g', 'b' keys.
	 */
	public function HTMLToRGB( $html_code ) {
		if ( '#' === $html_code[0] ) {
			$html_code = substr( $html_code, 1 );
		}

		if ( 3 === strlen( $html_code ) ) {
			$html_code = str_repeat( $html_code[0], 2 ) . str_repeat( $html_code[1], 2 ) . str_repeat( $html_code[2], 2 );
		}

		$r = hexdec( substr( $html_code, 0, 2 ) );
		$g = hexdec( substr( $html_code, 2, 2 ) );
		$b = hexdec( substr( $html_code, 4, 2 ) );

		return array(
			'r' => $r,
			'g' => $g,
			'b' => $b,
		);
	}

	/**
	 * Converts an RGB color array to an HSL object.
	 *
	 * @param array $rgb Associative array with 'r', 'g', 'b' keys (0-255).
	 * @return object Object with 'h' (0-360), 's' (0-100), 'l' (0-100) properties.
	 */
	public function RGBToHSL( array $rgb ) {
		$r = $rgb['r'] / 255;
		$g = $rgb['g'] / 255;
		$b = $rgb['b'] / 255;

		$max = max( $r, $g, $b );
		$min = min( $r, $g, $b );

		$h = 0;
		$s = 0;
		$l = ( $max + $min ) / 2;

		if ( $max !== $min ) {
			$d = $max - $min;
			$s = $l > 0.5 ? $d / ( 2 - $max - $min ) : $d / ( $max + $min );

			switch ( $max ) {
				case $r:
					$h = ( $g - $b ) / $d + ( $g < $b ? 6 : 0 );
					break;
				case $g:
					$h = ( $b - $r ) / $d + 2;
					break;
				case $b:
					$h = ( $r - $g ) / $d + 4;
					break;
			}
			$h /= 6;
		}

		return (object) array(
			'h' => round( $h * 360 ),
			's' => round( $s * 100 ),
			'l' => round( $l * 100 ),
		);
	}
}
