// Path: src/main/java/com/orange/dgil/trail/android/animation/AnimManager.java
// public class AnimManager {
// 
//   private final AnimRunnable animRunnable;
//   private final AnimParameters animParameters = new AnimParameters();
// 
//   public AnimManager(IAnimDrawer drawer) {
//     animRunnable = new AnimRunnable(drawer, animParameters);
//   }
// 
//   public void start() {
//     animRunnable.start();
//   }
// 
//   public int getAnimColor() {
//     int startColor = animParameters.getStartColor();
//     int endColor = animParameters.getEndColor();
//     return getInterpolatedColor(startColor, endColor, animRunnable.getFactor());
//   }
// 
//   public int getAnimShadowColor() {
//     int startColor = animParameters.getShadowStartColor();
//     int endColor = animParameters.getShadowEndColor();
//     return getInterpolatedColor(startColor, endColor, animRunnable.getFactor());
//   }
// 
//   private int getInterpolatedColor(int startColor, int endColor, float factor) {
//     return Color.argb(
//         getInterp(Color.alpha(startColor), Color.alpha(endColor), factor),
//         getInterp(Color.red  (startColor), Color.red  (endColor), factor),
//         getInterp(Color.green(startColor), Color.green(endColor), factor),
//         getInterp(Color.blue (startColor), Color.blue (endColor), factor));
//   }
//   private int getInterp(int start, int end, float factor) {
//     return (int) (start * factor + end * (1 - factor));
//   }
// 
// 
//   public float getFactor() {
//     return animRunnable.getFactor();
//   }
// 
//   /**
//    * The width factor is made to dilate the trail during fading
//    * @return the width factor
//    */
//   public float getWidthFactor() {
//     float factor = getFactor();
//     return 1 + animParameters.getWidthDilatationFactor() * (1-factor);
//   }
// 
//   public void reset() {
//     animRunnable.reset();
//   }
// 
//   public AnimParameters getAnimationParameters() {
//     return animParameters;
//   }
// 
//   public boolean isRunning() {
//     return animRunnable.isRunning();
//   }
// 
//   public boolean isAlphaAnimationRunning() {
//     return isRunning() && animParameters.areStartEndColorsRgbEqual();
//   }
// }
// 
// Path: src/main/java/com/orange/dgil/trail/android/drawingtool/DrawingToolsContext.java
// @RequiredArgsConstructor
// @Getter
// public class DrawingToolsContext {
//   private final View view;
//   private final AnimManager animManager;
//   private final AndroidMetrics androidMetrics;
//   private final TrailOptions trailOptions;
// }
// 
// Path: src/main/java/com/orange/dgil/trail/android/drawingtool/IDrawingTool.java
// public interface IDrawingTool {
//   void reset();
// 
//   void touchDown(int x, int y);
//   void touchMove(int x, int y);
//   void touchUp();
// 
//   void draw(Canvas c);
// 
//   void invalidateAreaOnMove();
//   void invalidatePath();
// 
//   void forceRedrawForAnimation(boolean eraseBitmap);
// 
//   void trimMemory();
// }
// 
// Path: src/main/java/com/orange/dgil/trail/core/common/TrailPoint.java
// @Getter
// @NoArgsConstructor
// public class TrailPoint {
//   private int x = -1;
//   private int y = -1;
// 
//   public TrailPoint(int x, int y) {
//     set(x, y);
//   }
// 
//   public void set(int x, int y) {
//     this.x = x;
//     this.y = y;
//   }
// 
//   public boolean isSameAs(TrailPoint point) {
//     return x == point.x && y == point.y;
//   }
// 
//   public double getDistanceTo(TrailPoint point) {
//     int dx = x - point.getX();
//     int dy = y - point.getY();
//     return Math.sqrt(dx * dx + dy * dy);
//   }
// 
//   public void deepCopy(TrailPoint point) {
//     x = point.x;
//     y = point.y;
//   }
// }


import android.graphics.Canvas;
import android.view.View;
import com.orange.dgil.trail.android.animation.AnimManager;
import com.orange.dgil.trail.android.drawingtool.DrawingToolsContext;
import com.orange.dgil.trail.android.drawingtool.IDrawingTool;
import com.orange.dgil.trail.core.common.TrailPoint;
import com.orange.dgil.trail.core.quad.QuadCurveArray;
    this.animManager = drawingToolsContext.getAnimManager();
    this.quadCurveArray = quadCurveArray;
    this.bitmapDrawer = bitmapDrawer;
    this.quillTrailBitmapListener = quillTrailBitmapListener;

    quillBitmap = new QuillBitmap(view);
    trailBounds = new TrailBounds(drawingToolsContext.getTrailOptions().getQuillParameters(), quadCurveArray.getTrailRect());
  }

  @Override
  public void reset() {
    if (quillBitmap.isLoaded()) {
      readIndex = 0;
      quillBitmap.reset();
    }
  }

  @Override
  public void trimMemory() {
    quillBitmap.releaseBitmap();
  }

  @Override
  public void forceRedrawForAnimation(boolean eraseBitmap) {
    quillBitmap.lazyLoading();
    bitmapDrawer.forceColor(animManager.getAnimColor());
    if (eraseBitmap) {
      quillBitmap.reset();
    }
    for (int i = 0; i <= quadCurveArray.getLastPointIndex(); i++) {
// Path: src/main/java/com/orange/dgil/trail/android/animation/AnimManager.java
// public class AnimManager {
// 
//   private final AnimRunnable animRunnable;
//   private final AnimParameters animParameters = new AnimParameters();
// 
//   public AnimManager(IAnimDrawer drawer) {
//     animRunnable = new AnimRunnable(drawer, animParameters);
//   }
// 
//   public void start() {
//     animRunnable.start();
//   }
// 
//   public int getAnimColor() {
//     int startColor = animParameters.getStartColor();
//     int endColor = animParameters.getEndColor();
//     return getInterpolatedColor(startColor, endColor, animRunnable.getFactor());
//   }
// 
//   public int getAnimShadowColor() {
//     int startColor = animParameters.getShadowStartColor();
//     int endColor = animParameters.getShadowEndColor();
//     return getInterpolatedColor(startColor, endColor, animRunnable.getFactor());
//   }
// 
//   private int getInterpolatedColor(int startColor, int endColor, float factor) {
//     return Color.argb(
//         getInterp(Color.alpha(startColor), Color.alpha(endColor), factor),
//         getInterp(Color.red  (startColor), Color.red  (endColor), factor),
//         getInterp(Color.green(startColor), Color.green(endColor), factor),
//         getInterp(Color.blue (startColor), Color.blue (endColor), factor));
//   }
//   private int getInterp(int start, int end, float factor) {
//     return (int) (start * factor + end * (1 - factor));
//   }
// 
// 
//   public float getFactor() {
//     return animRunnable.getFactor();
//   }
// 
//   /**
//    * The width factor is made to dilate the trail during fading
//    * @return the width factor
//    */
//   public float getWidthFactor() {
//     float factor = getFactor();
//     return 1 + animParameters.getWidthDilatationFactor() * (1-factor);
//   }
// 
//   public void reset() {
//     animRunnable.reset();
//   }
// 
//   public AnimParameters getAnimationParameters() {
//     return animParameters;
//   }
// 
//   public boolean isRunning() {
//     return animRunnable.isRunning();
//   }
// 
//   public boolean isAlphaAnimationRunning() {
//     return isRunning() && animParameters.areStartEndColorsRgbEqual();
//   }
// }
// 
// Path: src/main/java/com/orange/dgil/trail/android/drawingtool/DrawingToolsContext.java
// @RequiredArgsConstructor
// @Getter
// public class DrawingToolsContext {
//   private final View view;
//   private final AnimManager animManager;
//   private final AndroidMetrics androidMetrics;
//   private final TrailOptions trailOptions;
// }
// 
// Path: src/main/java/com/orange/dgil/trail/android/drawingtool/IDrawingTool.java
// public interface IDrawingTool {
//   void reset();
// 
//   void touchDown(int x, int y);
//   void touchMove(int x, int y);
//   void touchUp();
// 
//   void draw(Canvas c);
// 
//   void invalidateAreaOnMove();
//   void invalidatePath();
// 
//   void forceRedrawForAnimation(boolean eraseBitmap);
// 
//   void trimMemory();
// }
// 
// Path: src/main/java/com/orange/dgil/trail/core/common/TrailPoint.java
// @Getter
// @NoArgsConstructor
// public class TrailPoint {
//   private int x = -1;
//   private int y = -1;
// 
//   public TrailPoint(int x, int y) {
//     set(x, y);
//   }
// 
//   public void set(int x, int y) {
//     this.x = x;
//     this.y = y;
//   }
// 
//   public boolean isSameAs(TrailPoint point) {
//     return x == point.x && y == point.y;
//   }
// 
//   public double getDistanceTo(TrailPoint point) {
//     int dx = x - point.getX();
//     int dy = y - point.getY();
//     return Math.sqrt(dx * dx + dy * dy);
//   }
// 
//   public void deepCopy(TrailPoint point) {
//     x = point.x;
//     y = point.y;
//   }
// }


// Path: src/main/java/com/orange/dgil/trail/android/drawingtool/quillpen/QuillTrailBitmap.java
import android.graphics.Canvas;
import android.view.View;
import com.orange.dgil.trail.android.animation.AnimManager;
import com.orange.dgil.trail.android.drawingtool.DrawingToolsContext;
import com.orange.dgil.trail.android.drawingtool.IDrawingTool;
import com.orange.dgil.trail.core.common.TrailPoint;
import com.orange.dgil.trail.core.quad.QuadCurveArray;

    this.animManager = drawingToolsContext.getAnimManager();
    this.quadCurveArray = quadCurveArray;
    this.bitmapDrawer = bitmapDrawer;
    this.quillTrailBitmapListener = quillTrailBitmapListener;

    quillBitmap = new QuillBitmap(view);
    trailBounds = new TrailBounds(drawingToolsContext.getTrailOptions().getQuillParameters(), quadCurveArray.getTrailRect());
  }

  @Override
  public void reset() {
    if (quillBitmap.isLoaded()) {
      readIndex = 0;
      quillBitmap.reset();
    }
  }

  @Override
  public void trimMemory() {
    quillBitmap.releaseBitmap();
  }

  @Override
  public void forceRedrawForAnimation(boolean eraseBitmap) {
    quillBitmap.lazyLoading();
    bitmapDrawer.forceColor(animManager.getAnimColor());
    if (eraseBitmap) {
      quillBitmap.reset();
    }
    for (int i = 0; i <= quadCurveArray.getLastPointIndex(); i++) {
      TrailPoint point = quadCurveArray.get(i);