+ $title = 'All';
+ foreach ($chunks as $chunkGames) {
+ addDiscoverRow($data, $title, $chunkGames);
+ $title = '';
+ }
+
+ return $data;
+}
+
+/**
+ * Modify a category to make it suitable for the Razer Forge TV
+ *
+ * - Fold rows without title into the previous row
+ * - Remove automatically generated categories ("Last updated", "Best rated")
+ *
+ * @see buildDiscoverCategory()
+ */
+function convertCategoryToForge($data, $removeAutoCategories = false)
+{
+ //merge tiles from rows without title into the previous row
+ $lastTitleRowId = null;
+ foreach ($data['rows'] as $rowId => $row) {
+ if ($row['title'] !== '') {
+ $lastTitleRowId = $rowId;
+ } else if ($lastTitleRowId !== null) {
+ $data['rows'][$lastTitleRowId]['tiles'] = array_merge(
+ $data['rows'][$lastTitleRowId]['tiles'],
+ $row['tiles']
+ );
+ unset($data['rows'][$rowId]);
+ }
+ }
+
+ if ($removeAutoCategories) {
+ foreach ($data['rows'] as $rowId => $row) {
+ if ($row['title'] === 'Last updated'
+ || $row['title'] === 'Best rated'
+ ) {
+ unset($data['rows'][$rowId]);
+ }
+ }
+ }
+
+ $data['rows'] = array_values($data['rows']);
+
+ return $data;
+}
+
+function buildMakeCategory($name, $games)
+{
+ $data = [
+ 'title' => $name,
+ 'rows' => [],
+ 'tiles' => [],
+ ];
+
+ $games = sortByTitle($games);
+ addDiscoverRow($data, '', $games);
+
+ return $data;
+}
+
+/**
+ * Category without the "Last updated" or "Best rated" top rows
+ *
+ * Used for "Best rated", "Most rated", "Random"
+ */
+function buildSpecialCategory($name, $games)
+{
+ $data = [
+ 'title' => $name,
+ 'rows' => [],
+ 'tiles' => [],
+ ];
+
+ $first3 = array_slice($games, 0, 3);
+ $chunks = array_chunk(array_slice($games, 3), 4);
+ array_unshift($chunks, $first3);
+