<?php

function flexGetGroupSizePos($grpId, $data, $viewport = "desktop") {
  $allGroupsSizes = $data["groupsSizes"][$viewport];
  $sizePos = $allGroupsSizes[$grpId];
  $flatMap = $data["zIndexMaps"][$viewport];

  return [
    "top" => $sizePos["min_y"],
    "left" => $sizePos["min_x"],
    "width" => $sizePos["w"],
    "height" => $sizePos["h"],
    "z-index" => $flatMap[$grpId]
  ];
}

if (!function_exists('getGroupPropBool')) {
  function getGroupPropBool($group, $prop, $byDefault = "true") {
    if (isset($group[$prop]) && ($group[$prop] === "1" || $group[$prop] === true)) {
      return "true";
    } else if (isset($group[$prop]) && ($group[$prop] === "0" || $group[$prop] === false)) {
      return "false";
    } else if (!isset($group[$prop])) {
      return $byDefault;
    }
  }
}


// function flex_sort_by_position($a, $b) {
//   $atop = $a['top_position'];
//   $btop = $b['top_position'];
//   if ($atop === $btop) {
//     return 0;
//   }
//   return ($atop < $btop) ? -1 : 1;
// }

function flex_reorder_groups_elems($children, $elements, $desktopElements, $data, $viewport) {
  foreach ($children as $i => $child) {

    if ($child['type'] === 'gr') {
      $children[$i]['size_and_position'] = flexGetGroupSizePos($child["id"], $data, $viewport);
      $children[$i]['top_position'] = floatval(get_deep_value($children[$i], ['size_and_position', 'top'], 1));
    } else {

      $top_pos = get_deep_value($elements, [$child["id"], 'data', 'posY']);
      if ($top_pos || $top_pos == 0) {
        $children[$i]['top_position'] = floatval($top_pos);
      } else {
        $children[$i]['top_position'] = floatval($desktopElements[$child["id"]]['data']['posY']);
      }
    }
  }

  if (!get_deep_value($data, ["globalOptions", "htmlInLayerOrder"], false)) {
    usort($children, 'flex_sort_by_position');
  }

  return $children;
}

function flexRenderChildren($data, $children, $viewport, $parentSizePos = null) {
  $childrenMarkup = "";

  // get flat map if available (for z-indexes)
  $flatMap = isset($data["zIndexMaps"]) ? $data["zIndexMaps"][$viewport] : null;

  // get color names and send to renderer
  $colors = null;
  if (
    isset($data["globalOptions"]["themeColors"]) &&
    sizeof($data["globalOptions"]["themeColors"])
  ) {
    $colors = $data["globalOptions"]["themeColors"];
  } else {
    $stylekitData = Flex_Builder_Data::getFlexStylekitStyles(get_the_ID());

    if ($stylekitData) {
      $colors = $stylekitData['colors']['values'];
    }
  }

  // get elements obj
  if ($viewport === "desktop") {
    $elements = $data["elements"];
    $desktopElements = $elements;
  } else {
    $elements = $data["mobile_elements"];
    $desktopElements = $data["elements"];
  }

  $children = flex_reorder_groups_elems($children, $elements, $desktopElements, $data, $viewport);

  foreach ($children as $node) {
    if ($node["type"] === "gr") {
      $groupSizePos = $node["size_and_position"];

      $styleString = "";
      foreach ($groupSizePos as $sizePosKey => $sizePosVal) {
        if ($parentSizePos && ($sizePosKey === "top" || $sizePosKey === "left")) {
          $sizePosVal = $sizePosVal - $parentSizePos[$sizePosKey];
        }
        if ($sizePosKey !== "z-index") {
          $unit = "em";
        } else {
          $unit = "";
        }
        $styleString .= $sizePosKey . ":" . $sizePosVal . $unit . ";";
      }

      $childrenMarkup .= "<div
          style='" . $styleString . "'
          class='flex-group flex-group--" . $node["id"] . "'
          data-play-hover-animations='" . getGroupPropBool($node, "playHoverAnimations") . "'
          data-play-click-animations='" . getGroupPropBool($node, "playClickAnimations") . "'
          data-trigger-links='" . getGroupPropBool($node, "triggerLinks", "false") . "'
          data-clip-content='" . getGroupPropBool($node, "clipContent", "false") . "'
        >";

      $childrenMarkup .= flexRenderChildren($data, $node["children"], $viewport, $groupSizePos);
      $childrenMarkup .= "</div>";
    } else {
      $element = $elements[$node["id"]];
      $desktopElement = isset($desktopElements[$node["id"]]) ? $desktopElements[$node["id"]] : null;
      if ($viewport === "mobile" && isset($element['data']['synced']) && $element['data']['synced']) {
        if ($desktopElement) {
          $animations = isset($desktopElement['data']['user_data']['animations']) ? $desktopElement['data']['user_data']['animations'] : [];
          $element['data']['user_data'] = $desktopElement['data']['user_data'];
          $element['data']['user_data']['animations'] = $animations;
        }
      }
      $element['desktopElement'] = $desktopElement;
      $blockID = isset($data['blockID']) ? $data['blockID'] : uniqid('blockID--');
      $childrenMarkup .= flexRenderEl($element, $blockID, $flatMap, $colors, $viewport, $parentSizePos);
    }
  }
  return $childrenMarkup;
}

function flexRenderFromMap($data, $viewport = "desktop") {

  $maps = $data["maps"];
  $map = $maps[$viewport];
  $first_level_children = $map["children"];

  $markup = flexRenderChildren($data, $first_level_children, $viewport);

  return $markup;
}
