<?php
/**
 * Additional helper functions that the framework or themes may use.  The functions in this file are functions
 * that don't really have a home within any other parts of the framework.
 *
 * @package    HybridCore
 * @subpackage Includes
 * @author     Justin Tadlock <justin@justintadlock.com>
 * @copyright  Copyright (c) 2008 - 2015, Justin Tadlock
 * @link       http://themehybrid.com/hybrid-core
 * @license    http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 */

# Add extra support for post types.
add_action( 'init', 'hybrid_add_post_type_support', 15 );

# Filters the title for untitled posts.
add_filter( 'the_title', 'hybrid_untitled_post' );

# Filters the archive title and description.
add_filter( 'get_the_archive_title',       'hybrid_archive_title_filter',       5  );
add_filter( 'get_the_archive_description', 'hybrid_archive_description_filter', 0  );
add_filter( 'get_the_archive_description', 'hybrid_archive_description_format', 95 );

/**
 * This function is for adding extra support for features not default to the core post types.
 * Excerpts are added to the 'page' post type.  Comments and trackbacks are added for the
 * 'attachment' post type.  Technically, these are already used for attachments in core, but
 * they're not registered.
 *
 * @since 0.8.0
 * @access public
 * @return void
 */
function hybrid_add_post_type_support() {

	// Add support for excerpts to the 'page' post type.
	add_post_type_support( 'page', array( 'excerpt' ) );

	// Add thumbnail support for audio and video attachments.
	add_post_type_support( 'attachment:audio', 'thumbnail' );
	add_post_type_support( 'attachment:video', 'thumbnail' );

	// Add theme layouts support to core and custom post types.
	add_post_type_support( 'post',              'theme-layouts' );
	add_post_type_support( 'page',              'theme-layouts' );
	add_post_type_support( 'attachment',        'theme-layouts' );

	add_post_type_support( 'forum',             'theme-layouts' );
	add_post_type_support( 'literature',        'theme-layouts' );
	add_post_type_support( 'portfolio_item',    'theme-layouts' );
	add_post_type_support( 'portfolio_project', 'theme-layouts' );
	add_post_type_support( 'product',           'theme-layouts' );
	add_post_type_support( 'restaurant_item',   'theme-layouts' );
}

/**
 * This is a wrapper function for core WP's `get_theme_mod()` function.  Core doesn't
 * provide a filter hook for the default value (useful for child themes).  The purpose
 * of this function is to provide that additional filter hook.  To filter the final
 * theme mod, use the core `theme_mod_{$name}` filter hook.
 *
 * @since  3.1.0
 * @access public
 * @param  string  $name
 * @param  mixed   $default
 * @return mixed
 */
function hybrid_get_theme_mod( $name, $default = false ) {

	return get_theme_mod( $name, apply_filters( "hybrid_theme_mod_{$name}_default", $default ) );
}

/**
 * Function for setting the content width of a theme.  This does not check if a content width has been set; it
 * simply overwrites whatever the content width is.
 *
 * @since  1.2.0
 * @access public
 * @param  int    $width
 * @return void
 */
function hybrid_set_content_width( $width = '' ) {
	$GLOBALS['content_width'] = absint( $width );
}

/**
 * Function for getting the theme's content width.
 *
 * @since  1.2.0
 * @access public
 * @return int
 */
function hybrid_get_content_width() {
	return absint( $GLOBALS['content_width'] );
}

/**
 * The WordPress.org theme review requires that a link be provided to the single post page for untitled
 * posts.  This is a filter on 'the_title' so that an '(Untitled)' title appears in that scenario, allowing
 * for the normal method to work.
 *
 * @since  1.6.0
 * @access public
 * @param  string  $title
 * @return string
 */
function hybrid_untitled_post( $title ) {

	// Translators: Used as a placeholder for untitled posts on non-singular views.
	if ( ! $title && ! is_singular() && in_the_loop() && ! is_admin() )
		$title = esc_html__( '(Untitled)', 'hybrid-core' );

	return $title;
}

/**
 * Retrieves the file with the highest priority that exists.  The function searches both the stylesheet
 * and template directories.  This function is similar to the locate_template() function in WordPress
 * but returns the file name with the URI path instead of the directory path.
 *
 * @since  1.5.0
 * @access public
 * @link   http://core.trac.wordpress.org/ticket/18302
 * @param  array  $file_names The files to search for.
 * @return string
 */
function hybrid_locate_theme_file( $file_names ) {

	$located = '';

	// Loops through each of the given file names.
	foreach ( (array) $file_names as $file ) {

		// If the file exists in the stylesheet (child theme) directory.
		if ( is_child_theme() && file_exists( HYBRID_CHILD . $file ) ) {
			$located = HYBRID_CHILD_URI . $file;
			break;
		}

		// If the file exists in the template (parent theme) directory.
		elseif ( file_exists( HYBRID_PARENT . $file ) ) {
			$located = HYBRID_PARENT_URI . $file;
			break;
		}
	}

	return $located;
}

/**
 * Converts a hex color to RGB.  Returns the RGB values as an array.
 *
 * @since  2.0.0
 * @access public
 * @param  string  $hex
 * @return array
 */
function hybrid_hex_to_rgb( $hex ) {

	// Remove "#" if it was added.
	$color = trim( $hex, '#' );

	// If the color is three characters, convert it to six.
        if ( 3 === strlen( $color ) )
		$color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];

	// Get the red, green, and blue values.
	$red   = hexdec( $color[0] . $color[1] );
	$green = hexdec( $color[2] . $color[3] );
	$blue  = hexdec( $color[4] . $color[5] );

	// Return the RGB colors as an array.
	return array( 'r' => $red, 'g' => $green, 'b' => $blue );
}

/**
 * Function for grabbing a WP nav menu theme location name.
 *
 * @since  2.0.0
 * @access public
 * @param  string  $location
 * @return string
 */
function hybrid_get_menu_location_name( $location ) {

	$locations = get_registered_nav_menus();

	return isset( $locations[ $location ] ) ? $locations[ $location ] : '';
}

/**
 * Function for grabbing a WP nav menu name based on theme location.
 *
 * @since  3.0.0
 * @access public
 * @param  string  $location
 * @return string
 */
function hybrid_get_menu_name( $location ) {

	$locations = get_nav_menu_locations();

	$menu = isset( $locations[ $location ] ) ? wp_get_nav_menu_object( $locations[ $location ] ) : '';

	return $menu ? $menu->name : '';
}

/**
 * Helper function for getting the script/style `.min` suffix for minified files.
 *
 * @since  2.0.0
 * @access public
 * @return string
 */
function hybrid_get_min_suffix() {

	return hybrid_is_script_debug() ? '' : '.min';
}

/**
 * Conditional check to determine if we are in script debug mode.  This is generally used
 * to decide whether to load development versions of scripts/styles.
 *
 * @since  3.1.0
 * @access public
 * @return bool
 */
function hybrid_is_script_debug() {

	return apply_filters( 'hybrid_is_script_debug', defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
}

/**
 * Replaces `%1$s` and `%2$s` with the template and stylesheet directory paths.
 *
 * @since  3.1.0
 * @access public
 * @param  string  $value
 * @return string
 */
function hybrid_sprintf_theme_dir( $value ) {

	return sprintf( $value, get_template_directory(), get_stylesheet_directory() );
}

/**
 * Replaces `%1$s` and `%2$s` with the template and stylesheet directory URIs.
 *
 * @since  3.1.0
 * @access public
 * @param  string  $value
 * @return string
 */
function hybrid_sprintf_theme_uri( $value ) {

	return sprintf( $value, get_template_directory_uri(), get_stylesheet_directory_uri() );
}

/**
 * Utility function for including a file if a theme feature is supported and the file exists.  Note
 * that this should not be used in place of the core `require_if_theme_supports()` function.  We need
 * this particular function for checking if the file exists first, which the core function does not
 * handle at the moment.
 *
 * @since  3.0.0
 * @access public
 * @param  string  $feature
 * @param  string  $file
 * @return void
 */
function hybrid_require_if_theme_supports( $feature, $file ) {

	if ( current_theme_supports( $feature ) && file_exists( $file ) )
		require_once( $file );
}

/**
 * Filters `get_the_archve_title` to add better archive titles than core.
 *
 * @since  3.0.0
 * @access public
 * @param  string  $title
 * @return string
 */
function hybrid_archive_title_filter( $title ) {

	if ( is_home() && ! is_front_page() )
		$title = get_post_field( 'post_title', get_queried_object_id() );

	elseif ( is_category() )
		$title = single_cat_title( '', false );

	elseif ( is_tag() )
		$title = single_tag_title( '', false );

	elseif ( is_tax() )
		$title = single_term_title( '', false );

	elseif ( is_author() )
		$title = hybrid_get_single_author_title();

	elseif ( is_search() )
		$title = hybrid_get_search_title();

	elseif ( is_post_type_archive() )
		$title = post_type_archive_title( '', false );

	elseif ( get_query_var( 'minute' ) && get_query_var( 'hour' ) )
		$title = hybrid_get_single_minute_hour_title();

	elseif ( get_query_var( 'minute' ) )
		$title = hybrid_get_single_minute_title();

	elseif ( get_query_var( 'hour' ) )
		$title = hybrid_get_single_hour_title();

	elseif ( is_day() )
		$title = hybrid_get_single_day_title();

	elseif ( get_query_var( 'w' ) )
		$title = hybrid_get_single_week_title();

	elseif ( is_month() )
		$title = single_month_title( ' ', false );

	elseif ( is_year() )
		$title = hybrid_get_single_year_title();

	elseif ( is_archive() )
		$title = hybrid_get_single_archive_title();

	return apply_filters( 'hybrid_archive_title', $title );
}

/**
 * Filters `get_the_archve_description` to add better archive descriptions than core.
 *
 * @since  3.0.0
 * @access public
 * @param  string  $desc
 * @return string
 */
function hybrid_archive_description_filter( $desc ) {

	$new_desc = '';

	if ( is_home() && ! is_front_page() )
		$new_desc = get_post_field( 'post_content', get_queried_object_id(), 'raw' );

	elseif ( is_category() )
		$new_desc = get_term_field( 'description', get_queried_object_id(), 'category', 'raw' );

	elseif ( is_tag() )
		$new_desc = get_term_field( 'description', get_queried_object_id(), 'post_tag', 'raw' );

	elseif ( is_tax() )
		$new_desc = get_term_field( 'description', get_queried_object_id(), get_query_var( 'taxonomy' ), 'raw' );

	elseif ( is_author() )
		$new_desc = get_the_author_meta( 'description', get_query_var( 'author' ) );

	elseif ( is_post_type_archive() )
		$new_desc = get_post_type_object( get_query_var( 'post_type' ) )->description;

	return $new_desc ? $new_desc : $desc;
}

/**
 * Filters `get_the_archve_description` to add custom formatting.
 *
 * @since  3.1.0
 * @access public
 * @param  string  $desc
 * @return string
 */
function hybrid_archive_description_format( $desc ) {

	return apply_filters( 'hybrid_archive_description', $desc );
}

/**
 * Compatibility function that stores the old post template using the core WP
 * post template naming scheme added in WordPress 4.7.0.  Deletes the old
 * meta.
 *
 * @since  3.1.0
 * @access public
 * @param  int     $post_id
 * @param  string  $template
 * @return void
 */
function hybrid_post_template_compat( $post_id, $template ) {

	update_post_meta( $post_id, '_wp_page_template', $template );

	delete_post_meta( $post_id, sprintf( '_wp_%s_template', get_post_type( $post_id ) ) );
}
