<commit_before>;; 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) 2016 <NAME> <<EMAIL>>

(ns uxbox.main.geom
  (:require [uxbox.util.geom.matrix :as gmt]
            [uxbox.util.geom.point :as gpt]
            [uxbox.util.math :as mth]
            [uxbox.main.state :as st]))

;; --- Types

(def +hierarchy+
  (-> (make-hierarchy)
      (derive ::rect ::shape)
      (derive :icon ::rect)
      (derive :rect ::rect)
      (derive :circle ::shape)
      (derive :text ::rect)
      (derive :group ::rect)))

(defn shape?
  [type]
  (isa? +hierarchy+ type ::shape))

;; --- Relative Movement

(declare move-rect)
(declare move-path)
(declare move-circle)
(declare move-group)

(defn move
  "Move the shape relativelly to its current
  position applying the provided delta."
  [shape dpoint]
  (case (:type shape)
    :icon (move-rect shape dpoint)
    :icon-raw (move-rect shape dpoint)
    :rect (move-rect shape dpoint)
    :text (move-rect shape dpoint)
    :path (move-path shape dpoint)
    :circle (move-circle shape dpoint)
    :group (move-group shape dpoint)))

(defn- move-rect
  "A specialized function for relative movement
  for rect-like shapes."
  [shape {dx :x dy :y}]
  (assoc shape
         :x1 (mth/round (+ (:x1 shape) dx))
         :y1 (mth/round (+ (:y1 shape) dy))
         :x2 (mth/round (+ (:x2 shape) dx))
         :y2 (mth/round (+ (:y2 shape) dy))))

(defn- move-circle
  "A specialized function for relative movement
  for circle shapes."
  [shape {dx :x dy :y}]
  (assoc shape
         :cx (mth/round (+ (:cx shape) dx))
         :cy (mth/round (+ (:cy shape) dy))))

(defn- move-group
  "A specialized function for relative movement
  for group shapes."
  [shape {dx :x dy :y}]
  (assoc shape
         :dx (mth/round (+ (:dx shape 0) dx))
         :dy (mth/round (+ (:dy shape 0) dy))))

(defn- move-path
  "A specialized function for relative movement
  for path shapes."
  [shape {dx :x dy :y}]
  (let [points (:points shape)
        xf (comp
            (map #(update % :x + dx))
            (map #(update % :y + dy)))]
    (assoc shape :points (into [] xf points))))

;; --- Absolute Movement

(declare absolute-move-rect)
(declare absolute-move-circle)
(declare absolute-move-group)

(defn absolute-move
  "Move the shape to the exactly specified position."
  [shape point]
  (case (:type shape)
    :icon (absolute-move-rect shape point)
    :rect (absolute-move-rect shape point)
    :circle (absolute-move-circle shape point)
    :group (absolute-move-group shape point)))

(defn- absolute-move-rect
  "A specialized function for absolute moviment
  for rect-like shapes."
  [shape {:keys [x y] :as pos}]
  (let [dx (if x (- (:x1 shape) x) 0)
        dy (if y (- (:y1 shape) y) 0)]
    (move shape (gpt/point dx dy))))

(defn- absolute-move-circle
  "A specialized function for absolute moviment
  for rect-like shapes."
  [shape {:keys [x y] :as pos}]
  (let [dx (if x (- (:cx shape) x) 0)
        dy (if y (- (:cy shape) y) 0)]
    (move shape (gpt/point dx dy))))

(defn- absolute-move-group
  "A specialized function for absolute moviment
  for rect-like shapes."
  [shape {:keys [x y] :as pos}]
  (throw (ex-info "Not implemented (TODO)" {})))

;; --- Rotation

;; TODO: maybe we can consider apply the rotation
;;       directly to the shape coordinates?

(defn rotate
  "Apply the rotation to the shape."
  [shape rotation]
  (assoc shape :rotation rotation))

;; --- Size

(declare size-rect)
(declare size-circle)

(defn size
  "Calculate the size of the shape."
  [shape]
  (case (:type shape)
    :circle (size-circle shape)
    :text (size-rect shape)
    :rect (size-rect shape)
    :icon (size-rect shape)
    :icon-raw (size-rect shape)
    :image (size-rect shape)
    :path (size-rect shape)))

(defn- size-rect
  "A specialized function for calculate size
  for rect-like shapes."
  [{:keys [x1 y1 x2 y2] :as shape}]
  {:width (- x2 x1)
   :height (- y2 y1)})

(defn- size-circle
  "A specialized function for calculate size
  for circle shape."
  [{:keys [rx ry]}]
  {:width (* rx 2)
   :height (* ry 2)})

;; --- Vertex Access

(declare get-rect-vertext-point)
(declare get-circle-vertext-point)

(defn get-vertex-point
  [shape id]
  (case (:type shape)
    :icon (get-rect-vertext-point shape id)
    :rect (get-rect-vertext-point shape id)
    :circle (get-circle-vertext-point shape id)
    :text (get-rect-vertext-point shape id)))

(defn- get-rect-vertext-point
  [{:keys [x1 y1 x2 y2]} id]
  (case id
    :top-left (gpt/point x1 y1)
    :top-right (gpt/point x2 y1)
    :bottom-left (gpt/point x1 y2)
    :bottom-right (gpt/point x2 y2)
    :top (gpt/point (/ (+ x1 x2) 2) y1)
    :right (gpt/point x2 (/ (+ y1 y2) 2))
    :left (gpt/point x1 (/ (+ y1 y2) 2))
    :bottom (gpt/point (/ (+ x1 x2) 2)
                       (/ (+ y1 y2) 2))))

(defn- get-circle-vertext-point
  [{:keys [rx ry]} id]
  (gpt/point rx ry))

;; --- Vertex Movement (Relative)

(declare move-rect-vertex)
(declare move-circle-vertex)

(defn move-vertex
  "Resize the shape moving one of its vertex using<commit_msg>Add missing impl for icon-raw for get-vertex-point geom func.<commit_after>;; 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) 2016 <NAME> <<EMAIL>>

(ns uxbox.main.geom
  (:require [uxbox.util.geom.matrix :as gmt]
            [uxbox.util.geom.point :as gpt]
            [uxbox.util.math :as mth]
            [uxbox.main.state :as st]))

;; --- Types

(def +hierarchy+
  (-> (make-hierarchy)
      (derive ::rect ::shape)
      (derive :icon ::rect)
      (derive :rect ::rect)
      (derive :circle ::shape)
      (derive :text ::rect)
      (derive :group ::rect)))

(defn shape?
  [type]
  (isa? +hierarchy+ type ::shape))

;; --- Relative Movement

(declare move-rect)
(declare move-path)
(declare move-circle)
(declare move-group)

(defn move
  "Move the shape relativelly to its current
  position applying the provided delta."
  [shape dpoint]
  (case (:type shape)
    :icon (move-rect shape dpoint)
    :icon-raw (move-rect shape dpoint)
    :rect (move-rect shape dpoint)
    :text (move-rect shape dpoint)
    :path (move-path shape dpoint)
    :circle (move-circle shape dpoint)
    :group (move-group shape dpoint)))

(defn- move-rect
  "A specialized function for relative movement
  for rect-like shapes."
  [shape {dx :x dy :y}]
  (assoc shape
         :x1 (mth/round (+ (:x1 shape) dx))
         :y1 (mth/round (+ (:y1 shape) dy))
         :x2 (mth/round (+ (:x2 shape) dx))
         :y2 (mth/round (+ (:y2 shape) dy))))

(defn- move-circle
  "A specialized function for relative movement
  for circle shapes."
  [shape {dx :x dy :y}]
  (assoc shape
         :cx (mth/round (+ (:cx shape) dx))
         :cy (mth/round (+ (:cy shape) dy))))

(defn- move-group
  "A specialized function for relative movement
  for group shapes."
  [shape {dx :x dy :y}]
  (assoc shape
         :dx (mth/round (+ (:dx shape 0) dx))
         :dy (mth/round (+ (:dy shape 0) dy))))

(defn- move-path
  "A specialized function for relative movement
  for path shapes."
  [shape {dx :x dy :y}]
  (let [points (:points shape)
        xf (comp
            (map #(update % :x + dx))
            (map #(update % :y + dy)))]
    (assoc shape :points (into [] xf points))))

;; --- Absolute Movement

(declare absolute-move-rect)
(declare absolute-move-circle)
(declare absolute-move-group)

(defn absolute-move
  "Move the shape to the exactly specified position."
  [shape point]
  (case (:type shape)
    :icon (absolute-move-rect shape point)
    :rect (absolute-move-rect shape point)
    :circle (absolute-move-circle shape point)
    :group (absolute-move-group shape point)))

(defn- absolute-move-rect
  "A specialized function for absolute moviment
  for rect-like shapes."
  [shape {:keys [x y] :as pos}]
  (let [dx (if x (- (:x1 shape) x) 0)
        dy (if y (- (:y1 shape) y) 0)]
    (move shape (gpt/point dx dy))))

(defn- absolute-move-circle
  "A specialized function for absolute moviment
  for rect-like shapes."
  [shape {:keys [x y] :as pos}]
  (let [dx (if x (- (:cx shape) x) 0)
        dy (if y (- (:cy shape) y) 0)]
    (move shape (gpt/point dx dy))))

(defn- absolute-move-group
  "A specialized function for absolute moviment
  for rect-like shapes."
  [shape {:keys [x y] :as pos}]
  (throw (ex-info "Not implemented (TODO)" {})))

;; --- Rotation

;; TODO: maybe we can consider apply the rotation
;;       directly to the shape coordinates?

(defn rotate
  "Apply the rotation to the shape."
  [shape rotation]
  (assoc shape :rotation rotation))

;; --- Size

(declare size-rect)
(declare size-circle)

(defn size
  "Calculate the size of the shape."
  [shape]
  (case (:type shape)
    :circle (size-circle shape)
    :text (size-rect shape)
    :rect (size-rect shape)
    :icon (size-rect shape)
    :icon-raw (size-rect shape)
    :image (size-rect shape)
    :path (size-rect shape)))

(defn- size-rect
  "A specialized function for calculate size
  for rect-like shapes."
  [{:keys [x1 y1 x2 y2] :as shape}]
  {:width (- x2 x1)
   :height (- y2 y1)})

(defn- size-circle
  "A specialized function for calculate size
  for circle shape."
  [{:keys [rx ry]}]
  {:width (* rx 2)
   :height (* ry 2)})

;; --- Vertex Access

(declare get-rect-vertext-point)
(declare get-circle-vertext-point)

(defn get-vertex-point
  [shape id]
  (case (:type shape)
    :icon (get-rect-vertext-point shape id)
    :icon-raw (get-rect-vertext-point shape id)
    :rect (get-rect-vertext-point shape id)
    :circle (get-circle-vertext-point shape id)
    :text (get-rect-vertext-point shape id)))

(defn- get-rect-vertext-point
  [{:keys [x1 y1 x2 y2]} id]
  (case id
    :top-left (gpt/point x1 y1)
    :top-right (gpt/point x2 y1)
    :bottom-left (gpt/point x1 y2)
    :bottom-right (gpt/point x2 y2)
    :top (gpt/point (/ (+ x1 x2) 2) y1)
    :right (gpt/point x2 (/ (+ y1 y2) 2))
    :left (gpt/point x1 (/ (+ y1 y2) 2))
    :bottom (gpt/point (/ (+ x1 x2) 2)
                       (/ (+ y1 y2) 2))))

(defn- get-circle-vertext-point
  [{:keys [rx ry]} id]
  (gpt/point rx ry))

;; --- Vertex Movement (Relative)

(declare move-rect-vertex)
(declare move-circle-vertex)

(defn move-vertex
  "Resize the shape moving one of its vertex using
{'fraction_non_alphanumeric': 0.15308056872037915, 'fraction_numerical': 0.012132701421800948, 'mean_word_length': 2.7885098743267505, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2610432', 'n_tokens_mistral': 3834, 'n_tokens_neox': 3712, 'n_words': 1263}