                          (.printStackTrace e)))))
 
 (defn paint-all [container clipx clipy clipw cliph]
-  (let [ t (System/currentTimeMillis)
-         result (paint-component-with-children container nil)]
-      (do
-        ;(println "  -----Painted container in " (- (System/currentTimeMillis) t) " millis ")
-        result)))
-
-(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))])))
-
+  (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
 ;;

  "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))
    ))

(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)

          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)
          ]
        (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)))

;; 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")
;      [])))
