1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.replica.replicaisland;
18
19public class FadeDrawableComponent extends GameComponent {
20	public static final int LOOP_TYPE_NONE = 0;
21	public static final int LOOP_TYPE_LOOP = 1;
22	public static final int LOOP_TYPE_PING_PONG = 2;
23
24	public static final int FADE_LINEAR = 0;
25	public static final int FADE_EASE = 1;
26
27	private Texture mTexture;
28	private RenderComponent mRenderComponent;
29	private float mInitialOpacity;
30	private float mTargetOpacity;
31	private float mStartTime;
32	private float mDuration;
33	private int mLoopType;
34	private int mFunction;
35	private float mInitialDelay;
36	private float mInitialDelayTimer;
37	private float mActivateTime;
38	private float mPhaseDuration;
39
40	public FadeDrawableComponent() {
41		super();
42        setPhase(ComponentPhases.PRE_DRAW.ordinal());
43	}
44
45	@Override
46	public void reset() {
47		mTexture = null;
48		mRenderComponent = null;
49		mInitialOpacity = 0.0f;
50		mTargetOpacity = 0.0f;
51		mDuration = 0.0f;
52		mLoopType = LOOP_TYPE_NONE;
53		mFunction = FADE_LINEAR;
54		mStartTime = 0.0f;
55		mInitialDelay = 0.0f;
56		mActivateTime = 0.0f;
57		mPhaseDuration = 0.0f;
58		mInitialDelayTimer = 0.0f;
59	}
60
61	 @Override
62	 public void update(float timeDelta, BaseObject parent) {
63		 if (mRenderComponent != null) {
64			 final TimeSystem time = sSystemRegistry.timeSystem;
65			 final float currentTime = time.getGameTime();
66
67			 // Support repeating "phases" on top of the looping fade itself.
68			 // Complexity++, but it lets this component handle several
69			 // different use cases.
70			 if (mActivateTime == 0.0f) {
71				 mActivateTime = currentTime;
72				 mInitialDelayTimer = mInitialDelay;
73			 } else if (mPhaseDuration > 0.0f && currentTime - mActivateTime > mPhaseDuration) {
74				 mActivateTime = currentTime;
75				 mInitialDelayTimer = mInitialDelay;
76				 mStartTime = 0.0f;
77			 }
78
79			 if (mInitialDelayTimer > 0.0f) {
80				 mInitialDelayTimer -= timeDelta;
81			 } else {
82				 if (mStartTime == 0) {
83					 mStartTime = currentTime;
84				 }
85				 float elapsed = currentTime - mStartTime;
86				 float opacity = mInitialOpacity;
87				 if (mLoopType != LOOP_TYPE_NONE && elapsed > mDuration) {
88					 final float endTime = mStartTime + mDuration;
89					 elapsed = endTime - currentTime;
90					 mStartTime = endTime;
91					 if (mLoopType == LOOP_TYPE_PING_PONG) {
92						 float temp = mInitialOpacity;
93						 mInitialOpacity = mTargetOpacity;
94						 mTargetOpacity = temp;
95					 }
96				 }
97
98				 if (elapsed > mDuration) {
99					 opacity = mTargetOpacity;
100				 } else if (elapsed != 0.0f) {
101					 if (mFunction == FADE_LINEAR) {
102						 opacity = Lerp.lerp(mInitialOpacity, mTargetOpacity, mDuration, elapsed);
103					 } else if (mFunction == FADE_EASE) {
104						 opacity = Lerp.ease(mInitialOpacity, mTargetOpacity, mDuration, elapsed);
105					 }
106				 }
107
108				 if (mTexture != null) {
109					 // If a texture is set then we supply a drawable to the render component.
110					 // If not, we take whatever drawable the renderer already has.
111					 final DrawableFactory factory = sSystemRegistry.drawableFactory;
112		             if (factory != null) {
113		                 GameObject parentObject = ((GameObject)parent);
114		                 DrawableBitmap bitmap = factory.allocateDrawableBitmap();
115		                 bitmap.resize((int)mTexture.width, (int)mTexture.height);
116		                 //TODO: Super tricky scale.  fix this!
117		                 bitmap.setWidth((int)parentObject.width);
118		                 bitmap.setHeight((int)parentObject.height);
119		                 bitmap.setOpacity(opacity);
120		                 bitmap.setTexture(mTexture);
121		                 mRenderComponent.setDrawable(bitmap);
122		             }
123				 } else {
124					 DrawableObject drawable = mRenderComponent.getDrawable();
125					 // TODO: ack, instanceof!  Fix this!
126					 if (drawable != null && drawable instanceof DrawableBitmap) {
127						 ((DrawableBitmap)drawable).setOpacity(opacity);
128					 }
129				 }
130			 }
131		 }
132	 }
133
134	 public void setupFade(float startOpacity, float endOpacity, float duration, int loopType, int function, float initialDelay) {
135		 mInitialOpacity = startOpacity;
136		 mTargetOpacity = endOpacity;
137		 mDuration = duration;
138		 mLoopType = loopType;
139		 mFunction = function;
140		 mInitialDelay = initialDelay;
141	 }
142
143	 /** Enables phases; the initial delay will be re-started when the phase ends. **/
144	 public void setPhaseDuration(float duration) {
145		 mPhaseDuration = duration;
146	 }
147
148	 /** If set to something non-null, this component will overwrite the drawable on the target render component. **/
149	 public void setTexture(Texture texture) {
150		 mTexture = texture;
151	 }
152
153	 public void setRenderComponent(RenderComponent component) {
154		 mRenderComponent = component;
155	 }
156
157	 public void resetPhase() {
158		 mActivateTime = 0.0f;
159	 }
160}
161