<?php

/**
 * Render block
 */
class Flo_Flex_Builder_Render_Groups
{
	public $groups_flat_map = [];
	public $groups_props = [];

	public function __construct($data)
	{
		$this->parse_attributes($data);
	}

	public function parse_attributes($attributes)
	{
		foreach ($attributes as $prop_name => $prop_val) {
			$this->$prop_name = $prop_val;
		}
	}

	public function render()
	{
		$markup = '';
		$group_sizes = $this->groupsSizes;
		$map = $this->maps;

		// Create list of groups and their children
		foreach ($map as $device => $groups) {
			$this->walk_in_element_map($groups['children']);
		}

		if (isset($map['desktop'])) {
			$markup = $this->get_groups_markup($map['desktop']['children'], 'desktop', $group_sizes['desktop']);
		}

		if (isset($map['mobile'])) {
			$markup .= $this->get_groups_markup($map['mobile']['children'], 'mobile', $group_sizes['mobile']);
		}

		return $markup;
	}

	/**
	 * Creates an array of groups maped to their ID, value is an array of group
	 * content IDs (element IDs or other group IDs, if nested)
	 */
	public function walk_in_element_map($children, $group_id = NULL)
	{
		if ($group_id && !isset($this->groups_flat_map[$group_id])) {
			$this->groups_flat_map[$group_id] = [];
		}
		foreach ($children as $child) {
			if ($group_id) {
				$this->groups_flat_map[$group_id][] = $child['id'];
			}
			if ($child['type'] === 'gr') {
				$this->walk_in_element_map($child['children'], $child['id']);
				$this->flex_groups_props[$child['id']] = array_merge($child, ['children' => FALSE]);
			}
		}
	}

	/**
	 * Returns all elements from a specific group. Also nested elements
	 */
	public function get_elements_from_group($children, $all_groups)
	{
		$groups_and_els = '';

		foreach ($children as $child) {
			if (strpos($child, 'gr') !== FALSE) {
				$groups_and_els .= $this->get_elements_from_group($all_groups[$child], $all_groups);
			} else {
				$groups_and_els .= ' ' . $child;
			}
		}
		return $groups_and_els;
	}

	public function get_bool_prop($group, $prop, $byDefault = "true")
	{
		if (isset($group[$prop]) && ($group[$prop] === "1" || $group[$prop] === TRUE)) {
			return "true";
		} elseif (isset($group[$prop]) && ($group[$prop] === "0" || $group[$prop] === FALSE)) {
			return "false";
		} elseif (!isset($group[$prop])) {
			return $byDefault;
		}
	}

	/**
	 * Used for server-side group rendering
	 */
	public function get_group_styling($data)
	{
		return remove_new_lines('
		top: ' . flexParseNr($data['min_y']) . 'em;
		left: ' . flexParseNr($data['min_x']) . 'em;
		width: ' . flexParseNr($data['w']) . 'em;
		height: ' . flexParseNr($data['h']) . 'em;
    pointer-events: none;
	');
	}

	public function get_groups_markup($children, $device, $group_sizes)
	{
		$childrenMarkup = "";

		foreach ($children as $node) {
			if ($node["type"] === "gr") {
				$gr_id = $node['id'];

				$childrenMarkup .= '
        <div class="flex-group flex-group--' . $gr_id . ' server-rendered"
            data-device="' . $device . '"
            data-groups_and_elements="' . implode(",", $this->groups_flat_map[$gr_id]) . '"
            data-all_elements="' . $this->get_elements_from_group($this->groups_flat_map[$gr_id], $this->groups_flat_map) . '"
            data-play-hover-animations="' . $this->get_bool_prop($this->flex_groups_props[$gr_id], "playHoverAnimations") . '"
            data-play-click-animations="' . $this->get_bool_prop($this->flex_groups_props[$gr_id], "playClickAnimations") . '"
            data-trigger-links="' . $this->get_bool_prop($this->flex_groups_props[$gr_id], "triggerLinks", "false") . '"
            data-clip-content="' . $this->get_bool_prop($this->flex_groups_props[$gr_id], "clipContent", "false") . '"

            style="' . $this->get_group_styling($group_sizes[$gr_id]) . '">';

				$childrenMarkup = remove_new_lines($childrenMarkup);
				$childrenMarkup .= $this->get_groups_markup($node["children"], $device, $group_sizes);
				$childrenMarkup .= "</div>";
			}
		}
		return $childrenMarkup;
	}
}
