<?php
/**
 * Adds HTML markup.
 *
 * @package Nevo
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

if ( ! function_exists( 'nevo_body_classes' ) ) {
	add_filter( 'body_class', 'nevo_body_classes' );
	/**
	 * Adds custom classes to the array of body classes.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_body_classes( $classes ) {
		$is_blog = Nevo()->is_blog();
		$layout = nevo_get_post_setting('layout' );
		
		if ( $is_blog || is_category() || is_tag() || is_date() || is_author() ) {
			$classes[] = 'archive-post';
		}
		
		if ( is_single() && $layout ) {
			$classes[] = $layout;
		}
		
		if ( 'site-boxed' == Nevo()->get_setting( 'site_layout' ) ) {
			$classes[] = 'site-boxed';
		}
		
		$content_container = nevo_get_page_setting('content_container');

		if ( $content_container ) {
			if ( 'true' === $content_container ) {
				$classes[] = 'full-width-content';
			}
			if ( 'contained' === $content_container ) {
				$classes[] = 'contained-content';
			}
		}
		if ( is_customize_preview() ) {
			$classes[] = 'customize-preview';
		}

		return $classes;
	}
}

add_filter( 'nevo_page_class', 'nevo_page_classes' );
/**
 * Adds custom classes to the #page element
 *
 * @param array $classes The existing classes.
 * @since 1.0
 */
function nevo_page_classes( $classes ) {
	
	if ( 'nevo-container' == Nevo()->get_setting( 'site_layout' ) ) {
		$classes[] = 'nevo-container';
	}
	if ( 'box-shadow' == Nevo()->get_setting( 'site_box_shadow' ) ) {
		$classes[] = 'box-shadow';
	}
	$classes[] = Nevo()->get_setting( 'content_layout' );
	
	$default = Nevo()->get_setting( 'sidebar_layout' );
	
	$sidebar_layout = nevo_get_page_setting('sidebar_layout');
	
	if ( 'default' === $sidebar_layout ) {
		$sidebar_layout = $default;
	}
	$classes[] = ( $sidebar_layout ) ? $sidebar_layout : 'right-sidebar';
	
	return $classes;
}

add_filter( 'nevo_page_header_class', 'nevo_page_header_classes' );
/**
 * Adds custom classes to the #page header
 *
 * @param array $classes The existing classes.
 * @since 1.0
 */
function nevo_page_header_classes( $classes ) {
	//$classes[] = 'bg-secondary';
	
	if ( is_archive() && 'custom' == Nevo()->get_setting( 'post_archive_page_header_background_image' ) ) {
		$classes[] = 'custom';
	}
	if ( is_search() && 'custom' == Nevo()->get_setting( 'search_page_header_background_image' ) ) {
		$classes[] = 'custom';
	}
	if ( is_page() && 'custom' == Nevo()->get_setting( 'page_single_page_header_background_image' ) ) {
		$classes[] = 'custom';
	}
	if ( is_singular() && 'custom' == Nevo()->get_setting(  get_post_type() . '_single_page_header_background_image' ) ) {
		$classes[] = 'custom';
	}
	
	return $classes;
}

if ( ! function_exists( 'nevo_right_sidebar_classes' ) ) {
	add_filter( 'nevo_right_sidebar_class', 'nevo_right_sidebar_classes' );
	/**
	 * Adds custom classes to the right sidebar.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_right_sidebar_classes( $classes ) {
		$classes[] = 'widget-area';
		$classes[] = 'sidebar';
		$classes[] = 'is-right-sidebar';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_left_sidebar_classes' ) ) {
	add_filter( 'nevo_left_sidebar_class', 'nevo_left_sidebar_classes' );
	/**
	 * Adds custom classes to the left sidebar.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_left_sidebar_classes( $classes ) {
		$classes[] = 'widget-area';
		$classes[] = 'sidebar';
		$classes[] = 'is-left-sidebar';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_content_classes' ) ) {
	add_filter( 'nevo_content_class', 'nevo_content_classes' );
	/**
	 * Adds custom classes to the content container.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_content_classes( $classes ) {
		$classes[] = 'content-area';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_header_classes' ) ) {
	add_filter( 'nevo_header_class', 'nevo_header_classes' );
	/**
	 * Adds custom classes to the header.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_header_classes( $classes ) {
		$classes[] = 'site-header';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_menu_toggle_classes' ) ) {
	add_filter( 'nevo_menu_toggle_class', 'nevo_menu_toggle_classes' );
	/**
	 * Adds custom classes to the navigation.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_menu_toggle_classes( $classes ) {
		$classes[] = 'nevo-popup-toggle';
		$classes[] = 'd-flex';
		$classes[] = 'align-items-center';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_primary_navigation_classes' ) ) {
	add_filter( 'nevo_primary_navigation_class', 'nevo_primary_navigation_classes' );
	/**
	 * Adds custom classes to the navigation.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_primary_navigation_classes( $classes ) {
		$classes[] = 'nav-primary';
		$classes[] = 'builder-item-focus';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_secondary_navigation_classes' ) ) {
	add_filter( 'nevo_secondary_navigation_class', 'nevo_secondary_navigation_classes' );
	/**
	 * Adds custom classes to the navigation.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_secondary_navigation_classes( $classes ) {
		$classes[] = 'nav-secondary';
		$classes[] = 'builder-item-focus';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_mobile_navigation_classes' ) ) {
	add_filter( 'nevo_mobile_navigation_class', 'nevo_mobile_navigation_classes' );
	/**
	 * Adds custom classes to the navigation.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_mobile_navigation_classes( $classes ) {
		$classes[] = 'nav-mobile';
		$classes[] = 'position-relative';
		$classes[] = 'h-100';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_footer_navigation_classes' ) ) {
	add_filter( 'nevo_footer_navigation_class', 'nevo_footer_navigation_classes' );
	/**
	 * Adds custom classes to the navigation.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_footer_navigation_classes( $classes ) {
		$classes[] = 'nav-footer';
		$classes[] = 'position-relative';
		$classes[] = 'builder-item-focus';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_menu_classes' ) ) {
	add_filter( 'nevo_menu_class', 'nevo_menu_classes' );
	/**
	 * Adds custom classes to the menu.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_menu_classes( $classes ) {
		$classes[] = 'nevo-nav-menu';
		$classes[] = 'sf-menu';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_site_info_classes' ) ) {
	add_filter( 'nevo_site_info_class', 'nevo_site_info_classes' );
	/**
	 * Adds custom classes to the site info.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_site_info_classes( $classes ) {
		$classes[] = 'footer-section bottom-footer';

		return $classes;
	}
}

if ( ! function_exists( 'nevo_main_classes' ) ) {
	add_filter( 'nevo_main_class', 'nevo_main_classes' );
	/**
	 * Adds custom classes to the <main> element
	 *
	 * @param array $classes The existing classes.
	 * @since 1.1.0
	 */
	function nevo_main_classes( $classes ) {
		$classes[] = 'site-main';

		return $classes;
	}
}

add_filter( 'nevo_comment_author_class', 'nevo_do_comment_author_classes' );
/**
 * Adds custom classes to the comment author element
 *
 * @param array $classes The existing classes.
 * @since 1.0
 */
function nevo_do_comment_author_classes( $classes ) {
	$classes[] = 'comment-author vcard text-capitalize';

	return $classes;
}

if ( ! function_exists( 'nevo_post_classes' ) ) {
	add_filter( 'post_class', 'nevo_post_classes' );
	/**
	 * Adds custom classes to the <article> element.
	 * Remove .hentry class from pages to comply with structural data guidelines.
	 *
	 * @param array $classes The existing classes.
	 * @since 1.0
	 */
	function nevo_post_classes( $classes ) {
		if ( 'page' === get_post_type() ) {
			$classes = array_diff( $classes, array( 'hentry' ) );
		}

		return $classes;
	}
}


if ( ! function_exists( 'nevo_scroll_to_top_classes' ) ) {
	add_filter( 'nevo_scroll_to_top_class', 'nevo_scroll_to_top_classes' );
	/**
	 * Adds custom classes to the Scroll to Top.
	 *
	 * @param array $classes The existing classes.
	 * @since 0.1
	 */
	function nevo_scroll_to_top_classes( $classes ) {
		$classes['scroll-to-top'] = 'nevo-scroll-to-top';
		$classes['position'] = esc_attr( 'scrolltop-position-' . Nevo()->get_setting( 'scrolltop_position' ) );
		$classes['display'] = esc_attr( 'scrolltop-display-' . Nevo()->get_setting( 'scrolltop_display') );

		$visibility = Nevo()->get_setting( 'scrolltop_visibility', 'all' );

		$classes['visibility'] = nevo_create_visibility_classes( $visibility, 'd' );

		return $classes;
	}
}


/**
 * Display HTML classes for an element.
 *
 * @since 1.0
 *
 * @param string       $context The element we're targeting.
 * @param string|array $class One or more classes to add to the class list.
 */
function nevo_do_element_classes( $context, $class = '' ) {
	$after = apply_filters( 'nevo_after_element_class_attribute', '', $context );

	if ( $after ) {
		$after = ' ' . $after;
	}

	echo 'class="' . join( ' ', nevo_get_element_classes( $context, $class ) ) . '"' . $after; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in function.
}

/**
 * Retrieve HTML classes for an element.
 *
 * @since 1.0
 *
 * @param string       $context The element we're targeting.
 * @param string|array $class One or more classes to add to the class list.
 * @return array Array of classes.
 */
function nevo_get_element_classes( $context, $class = '' ) {
	$classes = array();

	if ( ! empty( $class ) ) {
		if ( ! is_array( $class ) ) {
			$class = preg_split( '#\s+#', $class );
		}

		$classes = array_merge( $classes, $class );
	}

	$classes = array_map( 'esc_attr', $classes );

	return apply_filters( "nevo_{$context}_class", $classes, $class );
}

/**
 * Get the kind of schema we're using.
 *
 * @since 1.0
 */
function nevo_get_schema_type() {
	return apply_filters( 'nevo_schema_type', 'microdata' );
}

/**
 * Get any necessary microdata.
 *
 * @since 1.0
 *
 * @param string $context The element to target.
 * @return string Our final attribute to add to the element.
 */
function nevo_get_microdata( $context ) {
	$data = false;

	if ( 'microdata' !== nevo_get_schema_type() ) {
		return false;
	}

	if ( 'body' === $context ) {
		$type = 'WebPage';

		if ( is_home() || is_archive() || is_attachment() || is_tax() || is_single() ) {
			$type = 'Blog';
		}

		if ( is_search() ) {
			$type = 'SearchResultsPage';
		}

		$type = apply_filters( 'nevo_body_itemtype', $type );

		$data = sprintf(
			'itemtype="https://schema.org/%s" itemscope',
			esc_html( $type )
		);
	}

	if ( 'header' === $context ) {
		$data = 'itemtype="https://schema.org/WPHeader" itemscope';
	}

	if ( 'primary_navigation' === $context ) {
		$data = 'itemtype="https://schema.org/SiteNavigationElement" itemscope';
	}

	if ( 'article' === $context ) {
		$type = apply_filters( 'nevo_article_itemtype', 'CreativeWork' );

		$data = sprintf(
			'itemtype="https://schema.org/%s" itemscope',
			esc_html( $type )
		);
	}

	if ( 'post-author' === $context ) {
		$data = 'itemprop="author" itemtype="https://schema.org/Person" itemscope';
	}

	if ( 'comment-body' === $context ) {
		$data = 'itemtype="https://schema.org/Comment" itemscope';
	}

	if ( 'comment-author' === $context ) {
		$data = 'itemprop="author" itemtype="https://schema.org/Person" itemscope';
	}

	if ( 'sidebar' === $context ) {
		$data = 'itemtype="https://schema.org/WPSideBar" itemscope';
	}

	if ( 'footer' === $context ) {
		$data = 'itemtype="https://schema.org/WPFooter" itemscope';
	}

	if ( $data ) {
		return apply_filters( "nevo_{$context}_microdata", $data );
	}
}

/**
 * Output our microdata for an element.
 *
 * @since 1.0
 *
 * @param string $context The element to target.
 */
function nevo_do_microdata( $context ) {
	echo nevo_get_microdata( $context ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in function.
}

/**
 * Merge array of attributes with defaults, and apply contextual filter on array.
 *
 * The contextual filter is of the form `nevo_attr_{context}`.
 *
 * @since 1.0
 *
 * @param string $context    The context, to build filter name.
 * @param array  $attributes Optional. Extra attributes to merge with defaults.
 * @param array  $settings   Optional. Custom data to pass to filter.
 * @return array Merged and filtered attributes.
 */
function nevo_parse_attr( $context, $attributes = array(), $settings = array() ) {
	// Initialize an empty class attribute so it's easier to append to in filters.
	if ( ! isset( $attributes['class'] ) ) {
		$attributes['class'] = '';
	}

	// We used to have a class-only system. If it's in use, add the classes.
	$classes = nevo_get_element_classes( $context );

	if ( $classes ) {
		$attributes['class'] .= join( ' ', $classes );
	}

	// Contextual filter.
	return apply_filters( 'nevo_parse_attr', $attributes, $context, $settings );
}

/**
 * Build list of attributes into a string and apply contextual filter on string.
 *
 * The contextual filter is of the form `nevo_attr_{context}_output`.
 *
 * @since 1.0
 *
 * @param string $context    The context, to build filter name.
 * @param array  $attributes Optional. Extra attributes to merge with defaults.
 * @param array  $settings   Optional. Custom data to pass to filter.
 * @return string String of HTML attributes and values.
 */
function nevo_get_attr( $context, $attributes = array(), $settings = array() ) {
	$attributes = nevo_parse_attr( $context, $attributes, $settings );

	$output = '';

	// Cycle through attributes, build tag attribute string.
	foreach ( $attributes as $key => $value ) {
		if ( ! $value ) {
			continue;
		}

		// Remove any whitespace at the start or end of our classes.
		if ( 'class' === $key ) {
			$value = trim( $value );
		}

		if ( true === $value ) {
			$output .= esc_html( $key ) . ' ';
		} else {
			$output .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
		}
	}

	// Before this function existed we had the below to add attributes after the class attribute.
	$after = apply_filters( 'nevo_after_element_class_attribute', '', $context );

	if ( $after ) {
		$after = ' ' . $after;
	}

	$output .= $after;

	$output = apply_filters( 'nevo_get_attr_output', $output, $attributes, $context, $settings );

	return trim( $output );
}

/**
 * Output our string of HTML attributes.
 *
 * @since 1.0
 *
 * @param string $context    The context, to build filter name.
 * @param array  $attributes Optional. Extra attributes to merge with defaults.
 * @param array  $settings   Optional. Custom data to pass to filter.
 */
function nevo_do_attr( $context, $attributes = array(), $settings = array() ) {
	echo nevo_get_attr( $context, $attributes, $settings ); // phpcs:ignore -- Escaping done in function.
}

add_filter( 'nevo_after_element_class_attribute', 'nevo_set_microdata_markup', 10, 2 );
/**
 * Adds microdata to elements.
 *
 * @since 1.0
 * @param string $output The existing output after the class attribute.
 * @param string $context What element we're targeting.
 */
function nevo_set_microdata_markup( $output, $context ) {
	if ( 'left_sidebar' === $context || 'right_sidebar' === $context ) {
		$context = 'sidebar';
	}

	if ( 'footer' === $context ) {
		return $output;
	}

	if ( 'site_info' === $context ) {
		$context = 'footer';
	}

	$microdata = nevo_get_microdata( $context );

	if ( $microdata ) {
		return $microdata;
	}

	return $output;
}
