<?php
/**
 * Flex @package SP Page Builder
 * Template Name - Flex
 * @author Aplikko http://www.aplikko.com
 * @copyright Copyright (c) 2025 Aplikko
 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later
*/
// no direct access
defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Layout\FileLayout;

class SppagebuilderAddonAnimated_headlines extends SppagebuilderAddons {

	public function render() {
		
		$settings = $this->addon->settings;

		$class = (isset($settings->class) && $settings->class) ? $settings->class : '';
		$before_text = (isset($settings->before_text) && $settings->before_text) ? $settings->before_text : '';
		$after_text = (isset($settings->after_text) && $settings->after_text) ? $settings->after_text : '';
		$alignment = (isset($settings->alignment) && $settings->alignment) ? $settings->alignment : '';
		$effect = (isset($settings->effect) && $settings->effect) ? $settings->effect : 'slide reset-width';
		$heading_selector = (isset($settings->heading_selector) && $settings->heading_selector) ? $settings->heading_selector : 'h2';
		$title_margin = (isset($settings->title_margin) && $settings->title_margin) ? $settings->title_margin : '';
		$title_padding = (isset($settings->title_padding) && $settings->title_padding) ? $settings->title_padding : '';
		
		$class = '';
		$output = '';
		$centered = '';
		$width_auto = '';
		$title_style = '';
		
		if($before_text && $after_text) {
			$centered = ' centered';
		}
		
		
		if ($effect == 'rotate-1 reset-width' || $effect == 'slide reset-width' || $effect == 'zoom reset-width' || $effect == 'push reset-width') {
			if ($before_text && $after_text) {
				$width_auto = '';
			} else {
				$width_auto = ' w-auto';
			}
		}
		
		if ($effect == 'clip is-full-width' || $effect == 'letters type') {
			if ($before_text && $after_text) {
				$width_auto = '';
			} else {
				$width_auto = ' px-0';
			}
		}

		$output  = '<div class="sppb-addon-animated_headlines ' . $alignment . ' ' . $class . '">';
		
		// Before Text
		$output .= '<'.$heading_selector.' class="sppb-addon-title animated_headlines '. $effect .'">';
		if($before_text) {
			$output .= '<span class="before-text match-height">';
			$output .= nl2br($before_text);
			$output .= '</span>';
		}
		$output .= '<span class="ah-words-wrapper'. (($effect == 'letters type') ? ' waiting' : '' ) .' match-height'. $width_auto .'">';
	
		// Repeatable Items
		foreach ($settings->sp_animated_headlines_item as $key => $value) {
			
			$headline_class = (isset($value->headline_class) && $value->headline_class) ? $value->headline_class : '';
			
			if($value->title) {
				$text = (isset($value->title) && $value->title) ? $value->title: '';
				$output .= '<b id="headline-'. ($this->addon->id + $key) .'"'. (($key == 0) ? ' class="is-visible match-height animated_headline'. $headline_class. '"': ' class="'. $headline_class .' match-height animated_headline'. $centered .'"' ) .'>';
				if ($effect == 'letters rotate-2' || $effect == 'letters rotate-3' || $effect == 'letters scale') {
					$text = str_replace(" ", "&nbsp;", $text); // add &nbsp; between words for "letters only" words
				}
				$output .= nl2br($text);
				$output .= '</b>';
			}
		}
		$output .= '</span>';
		// After Text
		if($after_text) {
			$output .= '<span class="after-text match-height">';
			$output .= nl2br($after_text);
			$output .= '</span>';
		}
		
		$output  .= '</'.$heading_selector.'>';
		$output  .= '</div>';

		return $output;
	}
	
	public function css() {
        
		$settings = $this->addon->settings;
		$addon_id = '#sppb-addon-' . $this->addon->id;
		$layout_path = JPATH_ROOT . '/components/com_sppagebuilder/layouts';
		
		$cssHelper = new CSSHelper($addon_id);

		
		$style = '';
		
        $heading_selector = (isset($settings->heading_selector) && $settings->heading_selector) ? $settings->heading_selector : 'h2';

		// Text shadow
        if(isset($settings->title_text_shadow) && is_object($settings->title_text_shadow)){
            $ho = (isset($settings->title_text_shadow->ho) && $settings->title_text_shadow->ho != '') ? $settings->title_text_shadow->ho.'px' : '0';
            $vo = (isset($settings->title_text_shadow->vo) && $settings->title_text_shadow->vo != '') ? $settings->title_text_shadow->vo.'px' : '0';
            $blur = (isset($settings->title_text_shadow->blur) && $settings->title_text_shadow->blur != '') ? $settings->title_text_shadow->blur.'px' : '0';
            $color = (isset($settings->title_text_shadow->color) && $settings->title_text_shadow->color != '') ? $settings->title_text_shadow->color : '#777';

            $style .= "text-shadow: {$ho} {$vo} {$blur} {$color};";
        }
		
		// Loading Bar
		$loading_bar = (isset($settings->loading_bar) && $settings->loading_bar) ? 'height: ' . $settings->loading_bar  . 'px;' : '';
		$loading_bar_color = (isset($settings->loading_bar_color) && $settings->loading_bar_color != '') ? 'background-color:' .$settings->loading_bar_color  . ';' : '';
		
		$typing_cursor_color = (isset($settings->typing_cursor_color) && $settings->typing_cursor_color != '') ? 'border-right:3px solid ' .$settings->typing_cursor_color  . ';' : '';
		
		$clip_cursor_color = (isset($settings->clip_cursor_color) && $settings->clip_cursor_color != '') ? 'background-color:' .$settings->clip_cursor_color  . ';' : '';

        $css = '';
		
		
		$headingProps = [
			'title_margin' => 'margin',
			'title_padding' => 'padding',
			'title_color' => 'color',
		];

		$headingUnit = [
			'title_margin' => false,
			'title_padding' => false,
			'title_color' => false,
		];

		$modifier = [
			'title_margin' => 'spacing',
			'title_padding' => 'spacing',
		];
		$heading = $cssHelper->generateStyle('.before-text, .ah-words-wrapper, .after-text', $settings, $headingProps, $headingUnit, $modifier);
		$css .= $heading;
		
		// Before and After text
		$css .= $addon_id . ' ' . $heading_selector . '.sppb-addon-title .before-text, '. $addon_id . ' ' . $heading_selector . '.sppb-addon-title .ah-words-wrapper, '. $addon_id . ' ' . $heading_selector . '.sppb-addon-title .after-text  {vertical-align:text-bottom;}';

		// Fix for padding (for the main headline/title) -- v.Flex 4.2
		$css .= ( (isset($settings->before_text) && $settings->before_text) && (isset($settings->after_text) && $settings->after_text) ) ? $addon_id . ' ' . $heading_selector . '.sppb-addon-title .ah-words-wrapper {padding-left:0!important;padding-right:0!important;}' : '';
		
		
		$headingTypography = $cssHelper->typography('.before-text, .ah-words-wrapper, .after-text', $settings, 'heading_typography', [
			'font'           => 'heading_font_family',
			'size'           => 'heading_fontsize',
			'line_height'    => 'heading_lineheight',
			'letter_spacing' => 'heading_letterspace',
			'uppercase'      => 'heading_font_style.uppercase',
			'italic'         => 'heading_font_style.italic',
			'underline'      => 'heading_font_style.underline',
			'weight'         => 'heading_font_style.weight'
		]);
		$css .= $headingTypography;
		
		
		// Implementing text shadow
   		if ($style) {
			$css .= $addon_id . ' ' . $heading_selector . '.sppb-addon-title .ah-words-wrapper {'. $style . '}';
        }
		
		if ($typing_cursor_color) {
			$css .= $addon_id . ' ' . $heading_selector . '.type .ah-words-wrapper::after {' . $typing_cursor_color .'}';
		}
		
		if ($clip_cursor_color) {
			$css .= $addon_id . ' ' . $heading_selector . '.clip .ah-words-wrapper::after {' . $clip_cursor_color .'}';
		}
		
		
		if ($loading_bar || $loading_bar_color) {
			$css .= $addon_id . ' ' . $heading_selector . '.loading-bar .ah-words-wrapper::after {' . $loading_bar . $loading_bar_color .'}';
		}
		
	
		// Repeatable Items
		$headline_style = '';
		$headline_fontstyle = '';	
		
		if(isset($settings->sp_animated_headlines_item) && count($settings->sp_animated_headlines_item)){
			foreach ($settings->sp_animated_headlines_item as $key => $value) {
				
				$headline_color = (isset($value->headline_color) && $value->headline_color != '') ? $value->headline_color : '';
				$headline_font_family = (isset($value->headline_font_family) && $value->headline_font_family != '') ? $value->headline_font_family : '';
				$headline_fontstyle = (isset($value->headline_fontstyle) && $value->headline_fontstyle != '') ? $value->headline_fontstyle : '';

				
				if($value->title) {
					
					$HeadlinesTextProps = [
						'headline_color' => 'color'
					];

					$HeadlinesTextUnit = [
						'headline_color' => false
					];
					
					// Flex 4.2 fix for repeatable headlines
					$HeadlinesText = $cssHelper->generateStyle('#headline-'. ($this->addon->id + $key), $value, $HeadlinesTextProps, $HeadlinesTextUnit);
					$HeadlinesStyle = $cssHelper->typography('#headline-'. ($this->addon->id + $key), $value, 'headline_font_family', [
						'font'           => 'heading_font_family',
						'size'           => 'heading_fontsize',
						'line_height'    => 'heading_lineheight',
						'letter_spacing' => 'heading_letterspace',
						'uppercase'      => 'heading_font_style.uppercase',
						'italic'         => 'heading_font_style.italic',
						'underline'      => 'heading_font_style.underline',
						'weight'         => 'heading_font_style.weight'
					]);
					
					$css .= $HeadlinesText;
					$css .= $HeadlinesStyle;
				}
			}
		}
        return $css;
    }

	public static function getTemplate() {
		
		$lodash = new Lodash('#sppb-addon-{{ data.id }}');

		$output = '
		<style type="text/css">';
		
		// Heading + "before" and "after" text
		$headingTypographyFallbacks = [
			'font'           => 'data.heading_font_family',
			'size'           => 'data.heading_fontsize',
			'line_height'    => 'data.heading_lineheight',
			'letter_spacing' => 'data.heading_letterspace',
			'uppercase'      => 'data.heading_font_style?.uppercase',
			'italic'         => 'data.heading_font_style?.italic',
			'underline'      => 'data.heading_font_style?.underline',
			'weight'         => 'data.heading_font_style?.weight'
		];
		$output .= $lodash->typography('.before-text, .ah-words-wrapper, .after-text', 'data.heading_typography', $headingTypographyFallbacks);
		
		
		$output .= $lodash->spacing('padding', '.before-text, .ah-words-wrapper, .after-text', 'data.title_padding');
		$output .= $lodash->spacing('margin', '.before-text, .ah-words-wrapper, .after-text', 'data.title_margin');
		$output .= $lodash->color('color', '.before-text, .ah-words-wrapper, .after-text', 'data.title_color');

		
		// Repeatable Headings
		$output .= '
		<# _.each(data.sp_animated_headlines_item, function (animated_headlines_item, key){ #>';

		// Animated text
		$HeadlinesTextTypographyFallbacks = [
			'font'           => 'animated_headlines_item.heading_font_family',
			'size'           => 'animated_headlines_item.heading_fontsize',
			'letter_spacing' => 'animated_headlines_item.heading_letterspace',
			'uppercase'      => 'animated_headlines_item.heading_font_style?.uppercase',
			'italic'         => 'animated_headlines_item.heading_font_style?.italic',
			'underline'      => 'animated_headlines_item.heading_font_style?.underline',
			'weight'         => 'animated_headlines_item.heading_font_style?.weight'
		];
		$output .= $lodash->color('color', '#headline-{{ data.id + key}}', 'animated_headlines_item.headline_color');
		
		$output .= $lodash->typography('#headline-{{ data.id + key }}', 'animated_headlines_item.headline_font_family', $HeadlinesTextTypographyFallbacks);

		$output .= ' <# }); #>';
		
		$output .= '</style>';
		
        $output .= '
		
        <#
		let animation_effect = (!_.isEmpty(data.effect) && data.effect) ? data.effect : "slide reset-width";
		
		let animated_text_class = "";
        if(animation_effect) {
            animated_text_class = "";
            if(animation_effect == "rotate-1 reset-width") {
                animated_text_class += "rotate-1 reset-width";
            } else if(animation_effect == "letters rotate-2") {
                animated_text_class += "letters rotate-2";
            } else if(animation_effect == "letters rotate-3") {
                animated_text_class += "letters rotate-3";	
			} else if(animation_effect == "letters type") {
                animated_text_class += "letters type waiting";
            } else if(animation_effect == "loading-bar") {
                animated_text_class += "loading-bar";
			} else if(animation_effect == "slide reset-width") {
                animated_text_class += "slide reset-width";	
            } else if(animation_effect == "clip is-full-width") {
                animated_text_class += "clip is-full-width";	
			} else if(animation_effect == "zoom reset-width") {
                animated_text_class += "zoom reset-width";
			} else if(animation_effect == "letters scale") {
                animated_text_class += "letters scale";
			} else if(animation_effect == "push reset-width") {
                animated_text_class += "push reset-width";	
            } else {
                animated_text_class += "slide reset-width";
            }
        }

            var titleTextShadow = "";
			if(_.isObject(data.title_text_shadow)){
				let ho = data.title_text_shadow.ho || 0,
					vo = data.title_text_shadow.vo || 0,
					blur = data.title_text_shadow.blur || 0,
					color = data.title_text_shadow.color || 0;

                titleTextShadow = ho+\'px \'+vo+\'px \'+blur+\'px \'+color;
			}
        #>
        <style type="text/css">
			#sppb-addon-{{ data.id }} .ah-words-wrapper{
                text-shadow: {{ titleTextShadow }};
				<# if(data.before_text || data.after_text) { #>
				padding-left:0!important;
				padding-right:0!important;
				<# } #>
            }
        </style>
		<div class="sppb-addon sppb-addon-animated_headlines {{ data.class }} {{ data.alignment }}">
			<{{ data.heading_selector }} class="animated_headlines {{ animated_text_class }}">
				<# if(data.before_text) { #>
					<span class="before-text match-height sp-inline-editable-element" data-id={{ data.id }} data-fieldName="before_text" contenteditable="true">{{{ data.before_text }}}</span>
				<# } #>
				<span class="ah-words-wrapper match-height">
				<# if(_.isArray(data.sp_animated_headlines_item)) {
					_.each(data.sp_animated_headlines_item, function(animated_headlines_item, key) { 
					var activeClass = (key == 0) ? "is-visible " : "";
					let animated_text = (!_.isEmpty(animated_headlines_item.title) && animated_headlines_item.title) ? animated_headlines_item.title : "";
					let animated_text_chunk = " ";
					animated_text_chunk = animated_text;
					#>
					<b id="headline-{{ data.id + key }}" class="{{ activeClass }} match-height animated_headline" data-id={{ data.id }} data-fieldName="highlighted_text" contenteditable="true">{{ animated_text_chunk }}</b>
				<# }) } #>
				</span>
				<# if(data.after_text) { #>
					<span class="after-text match-height sp-inline-editable-element" data-id={{ data.id }} data-fieldName="after_text" contenteditable="true">{{{ data.after_text }}}</span>
				<# } #>
			</{{ data.heading_selector }}>
        </div>
        ';

        return $output;
    }

}