;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC

(ns common-tests.helpers.files
  (:require
   [app.common.features :as ffeat]
   [app.common.geom.point :as gpt]
   [app.common.types.colors-list :as ctcl]
   [app.common.types.components-list :as ctkl]
   [app.common.types.container :as ctn]
   [app.common.types.file :as ctf]
   [app.common.types.pages-list :as ctpl]
   [app.common.types.shape :as cts]
   [app.common.types.shape-tree :as ctst]
   [app.common.types.typographies-list :as ctyl]
   [app.common.uuid :as uuid]))

(defn- make-file-data
  [file-id page-id]
  (binding [ffeat/*current* #{"components/v2"}]
    (ctf/make-file-data file-id page-id)))

(def ^:private idmap (atom {}))

(defn reset-idmap!
  [next]
  (reset! idmap {})
  (next))

(defn id
  [label]
  (get @idmap label))

(defn sample-file
  ([file-id page-id] (sample-file file-id page-id nil))
  ([file-id page-id props]
   (merge {:id file-id
           :name (get props :name "File1")
           :data (make-file-data file-id page-id)}
          props)))

(defn sample-shape
  [file label type page-id props]
  (ctf/update-file-data
   file
   (fn [file-data]
     (let [frame-id  (get props :frame-id uuid/zero)
           parent-id (get props :parent-id uuid/zero)
           shape     (cts/setup-shape
                      (-> {:type type
                           :width 1
                           :height 1}
                          (merge props)))]

       (swap! idmap assoc label (:id shape))
       (ctpl/update-page file-data
                         page-id
                         #(ctst/add-shape (:id shape)
                                          shape
                                          %
                                          frame-id
                                          parent-id
                                          0
                                          true))))))

(defn sample-component
  [file label page-id shape-id]
  (ctf/update-file-data
   file
   (fn [file-data]
     (let [page (ctpl/get-page file-data page-id)

           [component-shape component-shapes updated-shapes]
           (ctn/make-component-shape (ctn/get-shape page shape-id)
                                     (:objects page)
                                     (:id file)
                                     true)]

       (swap! idmap assoc label (:id component-shape))
       (-> file-data
           (ctpl/update-page page-id
                             #(reduce (fn [page shape] (ctst/set-shape page shape))
                                      %
                                      updated-shapes))
           (ctkl/add-component {:id (:id component-shape)
                                :name (:name component-shape)
                                :path ""
                                :main-instance-id shape-id
                                :main-instance-page page-id
                                :shapes component-shapes}))))))

(defn sample-instance
  [file label page-id library component-id]
  (ctf/update-file-data
   file
   (fn [file-data]
     (let [[instance-shape instance-shapes]
           (ctn/make-component-instance (ctpl/get-page file-data page-id)
                                        (ctkl/get-component (:data library) component-id)
                                        (:data library)
                                        (gpt/point 0 0)
                                        true)]

       (swap! idmap assoc label (:id instance-shape))
       (-> file-data
           (ctpl/update-page page-id
                             #(reduce (fn [page shape]
                                        (ctst/add-shape (:id shape)
                                                        shape
                                                        page
                                                        uuid/zero
                                                        (:parent-id shape)
                                                        0
                                                        true))
                                      %
                                      instance-shapes)))))))

(defn sample-color
  [file label props]
  (ctf/update-file-data
   file
   (fn [file-data]
     (let [id (uuid/next)
           props (merge {:id id
                         :name "Color 1"
                         :color "#000000"
                         :opacity 1}
                        props)]
       (swap! idmap assoc label id)
       (ctcl/add-color file-data props)))))

(defn sample-typography
  [file label props]
  (ctf/update-file-data
   file
   (fn [file-data]
     (let [id (uuid/next)
           props (merge {:id id
                         :name "Typography 1"
                         :font-id "sourcesanspro"
                         :font-family "sourcesanspro"
                         :font-size "14"
                         :font-style "normal"
                         :font-variant-id "regular"
                         :font-weight "400"
                         :line-height "1.2"
                         :letter-spacing "0"
                         :text-transform "none"}
                        props)]
       (swap! idmap assoc label id)
       (ctyl/add-typography file-data props)))))