package com.google.android.material.motion.operators;

import android.support.annotation.VisibleForTesting;
import android.support.v4.util.SimpleArrayMap;

import com.google.android.material.motion.MapOperation;
import com.google.android.material.motion.MotionObserver;
import com.google.android.material.motion.Operation;
import com.google.android.material.motion.SameTypedMapOperation;

import java.util.Map;

public final class Rewrite {

  @VisibleForTesting
  Rewrite() {
    throw new UnsupportedOperationException();
  }

  public static <T, U> Operation<T, U> rewriteTo(final U value) {
    return new MapOperation<T, U>() {
      @Override
      public U transform(T ignored) {
        return value;
      }
    };
  }

  public static <T, U> Operation<T, U> rewrite(T from, U to) {
    return new Operation<T, U>() {
      @Override
      public void next(MotionObserver<U> observer, T value) {
        if (value == from) {
          observer.next(to);
        }
      }
    };
  }

  public static <T, U> Operation<T, U> rewrite(T from1, U to1, T from2, U to2) {
    return new Operation<T, U>() {
      @Override
      public void next(MotionObserver<U> observer, T value) {
        if (value == from1) {
          observer.next(to1);
        } else if (value == from2) {
          observer.next(to2);
        }
      }
    };
  }

  public static <T, U> Operation<T, U> rewrite(T from1, U to1, T from2, U to2, T from3, U to3) {
    return new Operation<T, U>() {
      @Override
      public void next(MotionObserver<U> observer, T value) {
        if (value == from1) {
          observer.next(to1);
        } else if (value == from2) {
          observer.next(to2);
        } else if (value == from3) {
          observer.next(to3);
        }
      }
    };
  }

  public static <T, U> Operation<T, U> rewrite(final Map<T, U> map) {
    return new Operation<T, U>() {
      @Override
      public void next(MotionObserver<U> observer, T value) {
        if (map.containsKey(value)) {
          observer.next(map.get(value));
        }
      }
    };
  }

  public static <T, U> Operation<T, U> rewrite(final SimpleArrayMap<T, U> map) {
    return new Operation<T, U>() {
      @Override
      public void next(MotionObserver<U> observer, T value) {
        if (map.containsKey(value)) {
          observer.next(map.get(value));
        }
      }
    };
  }

  public static Operation<Float, Float> rewriteRange(
    final float start, final float end, final float destinationStart, final float destinationEnd) {
    return new SameTypedMapOperation<Float>() {
      @Override
      public Float transform(Float value) {
        float position = value - start;

        float vector = end - start;
        if (vector == 0) {
          return destinationStart;
        }
        float progress = position / vector;

        float destinationVector = destinationEnd - destinationStart;
        float destinationPosition = destinationVector * progress;

        return destinationStart + destinationPosition;
      }
    };
  }
}

@@ -726,1057 +726,8 @@
  %7D%0A%0A
-  public static %3CT, U%3E Operation%3CT, U%3E rewrite(T from, U to) %7B%0A    return new Operation%3CT, U%3E() %7B%0A      @Override%0A      public void next(MotionObserver%3CU%3E observer, T value) %7B%0A        if (value == from) %7B%0A          observer.next(to);%0A        %7D%0A      %7D%0A    %7D;%0A  %7D%0A%0A  public static %3CT, U%3E Operation%3CT, U%3E rewrite(T from1, U to1, T from2, U to2) %7B%0A    return new Operation%3CT, U%3E() %7B%0A      @Override%0A      public void next(MotionObserver%3CU%3E observer, T value) %7B%0A        if (value == from1) %7B%0A          observer.next(to1);%0A        %7D else if (value == from2) %7B%0A          observer.next(to2);%0A        %7D%0A      %7D%0A    %7D;%0A  %7D%0A%0A  public static %3CT, U%3E Operation%3CT, U%3E rewrite(T from1, U to1, T from2, U to2, T from3, U to3) %7B%0A    return new Operation%3CT, U%3E() %7B%0A      @Override%0A      public void next(MotionObserver%3CU%3E observer, T value) %7B%0A        if (value == from1) %7B%0A          observer.next(to1);%0A        %7D else if (value == from2) %7B%0A          observer.next(to2);%0A        %7D else if (value == from3) %7B%0A          observer.next(to3);%0A        %7D%0A      %7D%0A    %7D;%0A  %7D%0A%0A
   pu

Revert "rewrite"