 
 (defn shapes->rect-shape
   ([shapes] (shapes->rect-shape @st/state shapes))
-  ([state shapes]
+  ([state [shape :as shapes]]
    {:pre [(seq shapes)]}
    (let [shapes (map shape->rect-shape shapes)
          minx (apply min (map :x1 shapes))

  [{:keys [rx ry] :as shape}]
  (merge shape {: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)
    :image (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
  relative delta."
  [shape vid dpoint]
  (case (:type shape)
    :rect (move-rect-vertex shape vid dpoint)
    :text (move-rect-vertex shape vid dpoint)
    :icon (move-rect-vertex shape vid dpoint)
    :image (move-rect-vertex shape vid dpoint)
    :path (move-rect-vertex shape vid dpoint)
    :circle (move-circle-vertex shape vid dpoint)))

(defn- move-rect-vertex
  "A specialized function for vertex movement
  for rect-like shapes."
  [shape vid {dx :x dy :y lock? :lock}]
  (letfn [(handle-positioning [{:keys [x1 x2 y1 y2] :as shape}]
            (case vid
              :top-left (assoc shape
                               :x1 (min x2 (+ x1 dx))
                               :y1 (min y2 (+ y1 dy)))
              :top-right (assoc shape
                                :x2 (max x1 (+ x2 dx))
                                :y1 (min y2 (+ y1 dy)))
              :bottom-left (assoc shape
                                  :x1 (min x2 (+ x1 dx))
                                  :y2 (max y1 (+ y2 dy)))
              :bottom-right (assoc shape
                                   :x2 (max x1 (+ x2 dx))
                                   :y2 (max y1 (+ y2 dy)))
              :top (assoc shape :y1 (min y2 (+ y1 dy)))
              :right (assoc shape :x2 (max x1 (+ x2 dx)))
              :bottom (assoc shape :y2 (max y1 (+ y2 dy)))
              :left (assoc shape :x1 (min x2 (+ x1 dx)))))

          (handle-proportion [{:keys [y1 proportion proportion-lock] :as shape}]
            (let [{:keys [width height]} (size shape)]
              (if (or lock? proportion-lock)
                (assoc shape :y2 (+ y1 (/ width proportion)))
                shape)))]
    (-> shape
        (handle-positioning)
        (handle-proportion))))

(defn- move-circle-vertex
  "A specialized function for vertex movement
  for circle shapes."
  [shape vid {dx :x dy :y lock? :lock}]
  (letfn [(handle-positioning [shape]
            (case vid
              :top-left (assoc shape
                               :rx (max 0 (- (:rx shape) dx))
                               :ry (max 0 (- (:ry shape) dy)))
              :top-right (assoc shape
                                :rx (max 0 (+ (:rx shape) dx))
                                :ry (max 0 (- (:ry shape) dy)))
              :bottom-left (assoc shape
                                  :rx (max 0 (- (:rx shape) dx))
                                  :ry (max 0 (+ (:ry shape) dy)))
              :bottom-right (assoc shape
                                   :rx (max 0 (+ (:rx shape) dx))
                                   :ry (max 0 (+ (:ry shape) dy)))
              :top (assoc shape :ry (max 0 (- (:ry shape) dy)))
              :right (assoc shape :rx (max 0 (+ (:rx shape) dx)))
              :bottom (assoc shape :ry (max 0 (+ (:ry shape) dy)))
              :left (assoc shape :rx (max 0 (+ (:rx shape) dx)))))
          (handle-proportion [{:keys [rx proportion proportion-lock] :as shape}]
            (let [{:keys [width height]} (size shape)]
              (if (or lock? proportion-lock)
                (assoc shape :ry (/ rx proportion))
                shape)))]
    (-> shape
        (handle-positioning)
        (handle-proportion))))

;; --- Paths


  "A specialized function for absolute moviment
  for rect-like shapes."
  [shape {:keys [x y] :as pos}]
  (let [dx (if x (- x (:x1 shape)) 0)
        dy (if y (- y (:y1 shape)) 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 (- x(:cx shape)) 0)
        dy (if y (- y (:cy shape)) 0)]
    (move shape (gpt/point dx dy))))

(defn- absolute-move-group
