package com.github.florent37.expectanim;
import android.view.View;
import java.util.HashMap;
import java.util.Map;
import static java.lang.Math.abs;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
/**
* Created by florentchampigny on 20/02/2017.
*/
public class ViewCalculator {
private final Map<View, ViewExpectation> expectationForView;
private boolean enableRotation = true;
private boolean enableScale = true;
public ViewCalculator() {
expectationForView = new HashMap<>();
}
public void setExpectationForView(View view, ViewExpectation viewExpectation) {
expectationForView.put(view, viewExpectation);
}
public void wasCalculated(ViewExpectation viewExpectation) {
//no-op
}
public float finalPositionLeftOfView(View view, boolean itsMe) {
Float finalX = null;
final ViewExpectation viewExpectation = expectationForView.get(view);
if (viewExpectation != null) {
final Float futurPositionX = viewExpectation.getFuturPositionX();
if (futurPositionX != null) {
finalX = futurPositionX;
}
}
if (finalX == null) {
finalX = view.getX();
}
if (itsMe) {
finalX -= (view.getWidth() - this.finalWidthOfView(view)) / 2f;
}
return finalX;
}
public float finalPositionLeftOfView(View view) {
return finalPositionLeftOfView(view, false);
}
public float finalPositionRightOfView(View view) {
return finalPositionLeftOfView(view) + finalWidthOfView(view);
}
public float finalPositionTopOfView(View view, boolean itsMe) {
Float finalTop = null;
final ViewExpectation viewExpectation = expectationForView.get(view);
if (viewExpectation != null) {
final Float futurPositionY = viewExpectation.getFuturPositionY();
if (futurPositionY != null) {
finalTop = futurPositionY;
}
}
if (finalTop == null) {
finalTop = 1f * view.getTop();
}
if (itsMe) {
finalTop -= (view.getHeight() - this.finalHeightOfView(view)) / 2f;
}
return finalTop;
}
public float finalPositionTopOfView(View view) {
return finalPositionTopOfView(view, false);
}
public float finalPositionBottomOfView(View view) {
return finalPositionTopOfView(view) + finalHeightOfView(view);
}
public float finalCenterXOfView(View view) {
if (expectationForView.containsKey(view)) {
return expectationForView.get(view).getFuturPositionX() + finalWidthOfView(view) / 2f;
} else {
return view.getLeft() + view.getWidth() / 2f;
}
}
public float finalCenterYOfView(View view) {
if (expectationForView.containsKey(view)) {
return expectationForView.get(view).getFuturPositionY() + finalHeightOfView(view) / 2f;
} else {
return view.getTop() + view.getHeight() / 2f;
}
}
public float finalWidthOfView(View view) {
float with = view.getWidth();
if (expectationForView.containsKey(view)) {
final ViewExpectation viewExpectation = expectationForView.get(view);
with = widthScaled(viewExpectation, view, with);
if (enableRotation) {
with = widthRotated(viewExpectation, view, with);
}
}
return with;
}
private float widthScaled(ViewExpectation viewExpectation, View view, float width) {
final Float scaleX = viewExpectation.getWillHasScaleX();
if (scaleX != 1f) {
width = scaleX * width; // + view.getPivotX() * scaleX;
}
return width;
}
private float widthRotated(ViewExpectation viewExpectation, View view, float width) {
final Float willHaveRotationX = viewExpectation.getWillHaveRotation();
if (willHaveRotationX != null) {
final double radians = Math.toRadians(90 - willHaveRotationX);
width = (float) (abs(width * sin(radians)) + abs(heightScaled(viewExpectation, view, view.getHeight()) * cos(radians)));
}
return width;
}
public float finalHeightOfView(View view) {
float height = view.getHeight();
if (expectationForView.containsKey(view)) {
final ViewExpectation viewExpectation = expectationForView.get(view);
height = heightScaled(viewExpectation, view, height);
if (enableRotation) {
height = heightRotated(viewExpectation, view, height);
}
}
return height;
}
private float heightScaled(ViewExpectation viewExpectation, View view, float height) {
final Float scaleY = viewExpectation.getWillHasScaleY();
if (scaleY != 1) {
height = scaleY * height; // + view.getPivotY() * scaleY;
}
return height;
}
private float heightRotated(ViewExpectation viewExpectation, View view, float height) {
final Float willHaveRotationX = viewExpectation.getWillHaveRotation();
if (willHaveRotationX != null) {
final double radians = Math.toRadians(willHaveRotationX);
height = (float) (abs(height * cos(radians)) + abs(widthScaled(viewExpectation, view, view.getWidth()) * sin(radians)));
}
return height;
}
}