   "Paints component, does not pait children"
   (if (:visible cmpnt)
     (let [ look-vec (:look-vec cmpnt)]
-      (flatten-vector [ (if look-vec look-vec) (if (:has-trouble cmpnt) (trouble-look cmpnt dirty-rects)) ]))
-    ))
-
-(defn paint-component-only2 [cmpnt dirty-rects]
-  "Paints component, does not pait children"
-  (if (and (:visible cmpnt) (:look cmpnt))
-    (flatten-vector ((:look cmpnt) cmpnt dirty-rects))
-    ))
+      (flatten-vector [ (if look-vec look-vec) (if (:has-trouble cmpnt) (trouble-look cmpnt dirty-rects))]))))
 
 (defn paint-component-with-children [component dirty-rects]
   "Paints component and its children"
   (try
-    (let [ clip-w (m/x (:clip-size component))
-           clip-h (m/y (:clip-size component))
-           position-matrix (:position-matrix component)
-           viewport-matrix (:viewport-matrix component)
-
-          ;transform-matrix (m/mx* position-matrix viewport-matrix)
-          ;awt-transform-matrix (affinetransform transform-matrix)
-          ;awt-transform-matrix-inverse (invert awt-transform-matrix)
-
+    (let [clip-w (m/x (:clip-size component))
+          clip-h (m/y (:clip-size component))
+          position-matrix (:position-matrix component)
+          viewport-matrix (:viewport-matrix component)
           awt-position-matrix (awt/affinetransform position-matrix)
           awt-viewport-matrix (awt/affinetransform viewport-matrix)
           awt-viewport-matrix-inverse (awt/invert awt-viewport-matrix)
-          awt-position-matrix-inverse (awt/invert awt-position-matrix)
-          ]
+          awt-position-matrix-inverse (awt/invert awt-position-matrix)]
         (flatten-vector
           ; TODO WARNING! This is a temporary hack. Otherwise content-pane children do not respect table clip rect (not= (:widget-type component) "tablecell")
           [(if (not= (:widget-type component) "tablecell")  (awt/pushCurrentClip))

;         involved-components (get-all-components-for-dirty-rects container all-rects-to-paint)]
;    (paint-components (sort-components-by-id involved-components) all-rects-to-paint)))

;(defn- clip? [component] (not= (:widget-type component) "tablecell"))
; TODO
(defn- clip? [component] (#{"tablecontentpane" "window" "toolbar" "component" "tableheader"} (:widget-type component)))

(defn paint-dirty-impl [component dirty-rects force-paint]
  "Paints component and its children"
  (try
    (let [ clip-w (m/x (:clip-size component))
          clip-h (m/y (:clip-size component))
          position-matrix (:position-matrix component)
          viewport-matrix (:viewport-matrix component)

          ; TODO this is optimization for web: to transmit less commands
          transform-matrix (m/mx* position-matrix viewport-matrix)
          awt-transform-matrix (awt/affinetransform transform-matrix)
          awt-transform-matrix-inverse (awt/invert awt-transform-matrix)

          awt-position-matrix (awt/affinetransform position-matrix)
          awt-viewport-matrix (awt/affinetransform viewport-matrix)
          ;awt-viewport-matrix-inverse (invert awt-viewport-matrix)
          ;awt-position-matrix-inverse (invert awt-position-matrix)

          paint-this (or force-paint
                         (   ;or (nil? dirty-rects)
                           and dirty-rects
                               (r/intersect?
                                 dirty-rects
                                 {:x (m/mx-x (:abs-position-matrix component))
                                  :y (m/mx-y (:abs-position-matrix component))
                                  :w (m/x (:clip-size component))
                                  :h (m/y (:clip-size component))})))
          ;_ (if (= :main (:id component)) (println "Painting " (:id component) " paint=" paint-this " dirty-rects = " dirty-rects " abs pm = " (:abs-position-matrix component)))
          ;_ (if (and dirty-rects paint-this) (println "Painting " (:id component) " dirty-rects = " dirty-rects " abs pm = " (:abs-position-matrix component)))
          children (:children component)]
      (if paint-this
        (flatten-vector
          ; TODO WARNING! This is a temporary hack. Otherwise content-pane children do not respect table clip rect (not= (:widget-type component) "tablecell")
          [(if (clip? component)  (awt/pushCurrentClip))
           (awt/transform awt-position-matrix)

           (if (clip? component) (if (:popup component) (awt/setClip 0 0 clip-w clip-h) (awt/clipRect 0 0 clip-w clip-h)))
           (if (not= awt-viewport-matrix m/IDENTITY-MATRIX) (awt/transform awt-viewport-matrix))

           (paint-component-only2 component dirty-rects)
           ;(println "Painting component " (:id component) " :needs-repaint = " (:needs-repaint component))

           (mapv #(paint-dirty-impl % dirty-rects (and paint-this (not= :main (:id component)))) (sort-by :z-position (for [[_ v] (:children component)] v)))

           ;(transform awt-viewport-matrix-inverse)
           ;(transform awt-position-matrix-inverse)
           (awt/transform awt-transform-matrix-inverse)

           (if (clip? component) (awt/popCurrentClip))
           ])
        (if (seq children)
          (let [ children-look (mapv #(paint-dirty-impl % dirty-rects false) (sort-by :z-position (for [[_ v] children] v)))]
            (if (seq children-look)
              (flatten-vector
                [                                               ;(transform awt-transform-matrix)
                 (if (clip? component)  (awt/pushCurrentClip))
                 (awt/transform awt-position-matrix)
                 (if (clip? component) (if (:popup component) (awt/setClip 0 0 clip-w clip-h) (awt/clipRect 0 0 clip-w clip-h)))
                 (if (not= awt-viewport-matrix m/IDENTITY-MATRIX) (awt/transform awt-viewport-matrix))

                 children-look

                 (awt/transform awt-transform-matrix-inverse)
                 (if (clip? component) (awt/popCurrentClip))
                 ;(transform awt-transform-matrix-inverse)
                 ])
              (do
                ;(println "Chidren look skipped")
                nil)))
          )))
    (catch Exception e (do
                         (fg/log-debug "Exception " (.getMessage e)
                                    " when painting component id = " (:id component)
                                    ;" component: " (container-to-str component)
                                    )
                         (.printStackTrace e)))))

(defn paint-dirty [component _ _]
  (if (:dirty-rect component)
    (do
      ;(println "Dirty rect is " (:dirty-rect component) " painting...")
      (paint-dirty-impl component (:dirty-rect component) nil))
    (do
      ;(println " Dirty rect is null, skipped painting")
      [])))


;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;; New painting approach optimized for web
;;;;;;;;;;;;;;;;;;;;;;;;

(defmulti extract-value (fn [property _ _] (class property)))

(defmethod extract-value Keyword [property f container]
  (f (property container)))

(defmethod extract-value Collection [property f container]
  ;; This reduce accumulates bit flags
  (reduce #(+ (* 2 %1) %2) 0 (for [p property] (f (p container)))))

(defn- get-component-id-path-to-property-value [id-path container property f]
  (let [this-id-path (fgc/conjv id-path (:id container))]
    (apply
      merge
      {this-id-path (extract-value property f container)}
      (for [[_ v] (:children container)] (get-component-id-path-to-property-value this-id-path v property f)))))

(defn get-component-id-path-to-position-matrix [container]
  (get-component-id-path-to-property-value [] container :position-matrix awt/affinetransform))

(defn get-component-id-path-to-viewport-matrix [container]
  (get-component-id-path-to-property-value [] container :viewport-matrix awt/affinetransform))

(defn get-component-id-path-to-clip-size [container]
  (get-component-id-path-to-property-value [] container :clip-size (fn [c] [(m/x c) (m/y c)])))

(defn get-component-id-path-to-look-vector [container]
  (get-component-id-path-to-property-value [] container :look-vec identity))

(defn get-component-id-path-to-child-count [container]
  (get-component-id-path-to-property-value [] container :children count))

(defn get-component-id-path-to-flags [container]
  (get-component-id-path-to-property-value [] container [:rollover-notify-disabled :popup :visible] (fn [v] (if v 1 0))))

(defn get-component-id-path-to-image-url [container]
      (get-component-id-path-to-property-value [] container :image-url identity))

(defn- ready-for-paint? [container]
  (and
    (:position-matrix container)
    (:viewport-matrix container)
    (:clip-size container)
    (:look-vec container)))

;;;
;;; TODO sort by z-order here?
;;;
(defn get-paint-all-sequence
  ([id-path container]
    (if (ready-for-paint? container)
      (apply concat
             [(conj id-path (:id container))]
             (for [[_ v] (:children container)] (get-paint-all-sequence (conj id-path (:id container)) v)))
     []))
  ([container] (get-paint-all-sequence [] container)))
                         (.printStackTrace e)))))

(defn paint-all [container clipx clipy clipw cliph]
  (paint-component-with-children container nil))

;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;; New painting approach optimized for web
;;;;;;;;;;;;;;;;;;;;;;;;

(defmulti extract-value (fn [property _ _] (class property)))

(defmethod extract-value Keyword [property f container]
  (f (property container)))

(defmethod extract-value Collection [property f container]
  ;; This reduce accumulates bit flags
  (reduce #(+ (* 2 %1) %2) 0 (for [p property] (f (p container)))))

(defn- get-component-id-path-to-property-value [id-path container property f]
  (let [this-id-path (fgc/conjv id-path (:id container))]
    (apply
      merge
      {this-id-path (extract-value property f container)}
      (for [[_ v] (:children container)] (get-component-id-path-to-property-value this-id-path v property f)))))

(defn get-component-id-path-to-position-matrix [container]
  (get-component-id-path-to-property-value [] container :position-matrix awt/affinetransform))

(defn get-component-id-path-to-viewport-matrix [container]
  (get-component-id-path-to-property-value [] container :viewport-matrix awt/affinetransform))

(defn get-component-id-path-to-clip-size [container]
  (get-component-id-path-to-property-value [] container :clip-size (fn [c] [(m/x c) (m/y c)])))

(defn get-component-id-path-to-look-vector [container]
  (get-component-id-path-to-property-value [] container :look-vec identity))

(defn get-component-id-path-to-child-count [container]
  (get-component-id-path-to-property-value [] container :children count))

(defn get-component-id-path-to-flags [container]
  (get-component-id-path-to-property-value [] container [:rollover-notify-disabled :popup :visible] (fn [v] (if v 1 0))))

(defn get-component-id-path-to-image-url [container]
      (get-component-id-path-to-property-value [] container :image-url identity))

(defn- ready-for-paint? [container]
  (and
    (:position-matrix container)
    (:viewport-matrix container)
    (:clip-size container)
    (:look-vec container)))

;;;
;;; TODO sort by z-order here?
;;;
(defn get-paint-all-sequence
  ([id-path container]
    (if (ready-for-paint? container)
      (apply concat
             [(conj id-path (:id container))]
             (for [[_ v] (:children container)] (get-paint-all-sequence (conj id-path (:id container)) v)))
     []))
  ([container] (get-paint-all-sequence [] container)))



;;;;;;;;;;;;;;
;;;;;;;;;;;;;; Old experimental approaches
;;;;;;;;;;;;;;

;(defn paint-component-only2 [cmpnt dirty-rects]
;  "Paints component, does not pait children"
;  (if (and (:visible cmpnt) (:look cmpnt))
;    (flatten-vector ((:look cmpnt) cmpnt dirty-rects))
;    ))

;(defn get-dirty-rect-from-container [container]
;  (let [ r (:dirty-rect container)]
;    (if r
;      [(double (:x r)) (double (:y r)) (double (:w r)) (double (:h r))])))

;;@todo with such approach clip rect should be passed to evolve
;;
