 (defn convert-degree-to-radian [degree]
   (* degree (/ Math/PI 180)))
 
-;;Compute boost value between 0 and 100
+;; Conversion degrés en radians :
+;; rad  = degrés * M_PI / 180
+(defn convert-radian-to-degree [radian]
+  (* radian (/ 180 Math/PI)))
+
+;; Conversion d'un double en entier avec arrondi
+(defn convert-to-int [float-value] 
+ (Integer/valueOf (Math/round float-value)))
+
+;;Angle entre 2 points (x1,y1) et (x2,y2)
+(defn angle-between-2-points [x1 y1 x2 y2] 
+  (let [ d (distance x1 y1 x2 y2) dx (/ (- x2 x1) d) dy (/ (- y2 y1) d) angle (convert-radian-to-degree (Math/acos dx))] 
+    (if (< dy 0) (- 360.0 angle) angle)))
+
+(defn after [val1 val2] (if (> (- val2 val1) 0) true false))
+(defn before [val1 val2] (if (< (- val2 val1) 0) true false))
+
+;;Compute a boost value between 0 and 100
 (defn compute-boost [next-checkpoint-distance next-checkpoint-angle]
   (cond
     (> (Math/abs next-checkpoint-angle) 90) "0"
+    (and (< next-checkpoint-distance 1000) (> (Math/abs next-checkpoint-angle) 30)) "0"
+    ;;(and (< next-checkpoint-distance 1000) (< (Math/abs next-checkpoint-angle) 30)) "50"
     (< (Math/abs next-checkpoint-angle) 30) "100"
-    (and (< next-checkpoint-distance 1000) (> (Math/abs next-checkpoint-angle) 30)) "0"
-    (and (< next-checkpoint-distance 1000) (< (Math/abs next-checkpoint-angle) 30)) "50"
     (> next-checkpoint-distance 4000) "100"
     true (str (Integer/valueOf (Math/round (* 100 (Math/abs (Math/cos (convert-degree-to-radian next-checkpoint-angle)))))))))
 
-(defn compute-x [next-checkpoint-x] next-checkpoint-x)
+(defn compute-x [x next-checkpoint-x next-checkpoint-angle next-checkpoint-distance] 
+  (if (> next-checkpoint-distance 1000)
+    (cond
+      (and (>= next-checkpoint-angle -90) (<= next-checkpoint-angle 90) (before next-checkpoint-x x)) 
+        (convert-to-int (+ next-checkpoint-x (* checkpoint-core-size (Math/cos next-checkpoint-angle))))
+      (and (>= next-checkpoint-angle -90) (<= next-checkpoint-angle 90) (after next-checkpoint-x x)) 
+        (convert-to-int (- next-checkpoint-x (* checkpoint-core-size (Math/cos next-checkpoint-angle))))  
+      (or (<= -180 next-checkpoint-angle -90 ) (>= 180 next-checkpoint-angle 90)) 
+        (convert-to-int (- next-checkpoint-x (* checkpoint-core-size (Math/cos next-checkpoint-angle))))) 
+    next-checkpoint-x))
 
-(defn compute-y [next-checkpoint-y] next-checkpoint-y)
+(defn compute-y [y next-checkpoint-y next-checkpoint-angle next-checkpoint-distance] 
+  (if (cond
+        (and (>= next-checkpoint-angle 0)  (<= next-checkpoint-angle 180)) (convert-to-int (- next-checkpoint-y (* checkpoint-core-size (Math/sin next-checkpoint-angle))))
+        (and (< next-checkpoint-angle 0) (>= next-checkpoint-angle -180)) (convert-to-int (+ next-checkpoint-y (* checkpoint-core-size (Math/sin next-checkpoint-angle))))) 
+   next-checkpoint-y))
 
 (def boost-used? (atom false))
 (def game-loop-counter (atom 0))

(ns coders-strike-back.core
  (:gen-class))

(defn inc-atom [curr-val] (inc curr-val))
(defn dec-atom [curr-val] (dec curr-val))

                  ; (binding [*out* *err*]
                  ;   (println "Debug messages..."))
                  (binding [*out* *err*]
                    (println (str "Has the boost been used ? : " @boost-used?))
                    (println (str "Next check point distance coordinates : (" nextCheckpointX "," nextCheckpointY ")"))
                    (println (str "Given next check point distance : " nextCheckpointDist))
                    (println (str "Calculated next check point distance : " (distance x y nextCheckpointX nextCheckpointY)))
                    (println (str "Pod angle with checkpoint : " nextCheckpointAngle))
                    (println (str "Calculated Pod angle with checkpoint : " (angle-between-2-points x y nextCheckpointX nextCheckpointY)))
                    (println (str "Pod Position : (" x "," y ")"))
                    (println (str "Opponent pod Position : (" opponentX "," opponentY ")"))
                    (println (str "Opponent distance : " opponent-distance))
                    (println (str "Calculated Pod angle with opponent : " (angle-between-2-points x y opponentX opponentY)))
                    (println (str "Game loop counter : " @game-loop-counter)))
                    

                  ; You have to output the target position
                  ; followed by the power (0 <= thrust <= 100)
                  ; i.e.: "x y thrust"
                  (print (compute-x x nextCheckpointX nextCheckpointAngle nextCheckpointDist))
                  (print " ")
                  (print (compute-y y nextCheckpointY nextCheckpointAngle nextCheckpointDist))
                  (print " ")
                  (print (compute-action
                           nextCheckpointX nextCheckpointY
                           nextCheckpointDist nextCheckpointAngle
                           opponentX opponentY
                           boost-used? game-loop-counter)))
        (println "")))
