Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / animations / FUiAnim_TransactionNode.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FUiAnim_TransactionNode.cpp
20  * @brief       This file contains implementation of _TransactionNode class
21  *
22  * This file contains implementation _TransactionNode class.
23  */
24
25 #include <FBaseSysLog.h>
26
27 #include <FUiAnimIVisualElementAnimationStatusEventListener.h>
28 #include <FUiAnimIVisualElementAnimationTickEventListener.h>
29 #include <FUiAnimIVisualElementAnimationValueInterpolator.h>
30 #include <FUiAnimIAnimationTransactionEventListener.h>
31 #include <FUiAnimVisualElementPropertyAnimation.h>
32 #include <FUiAnimVisualElement.h>
33
34 #include "FUi_Math.h"
35 #include "FUi_EcoreEvas.h"
36 #include "FUiAnim_VisualElementValueAnimationImpl.h"
37 #include "FUiAnim_VisualElementAnimationKeyFrame.h"
38 #include "FUiAnim_TransactionNode.h"
39 #include "FUiAnim_Debug.h"
40
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Collection;
43
44 //#define VE_DEBUG_ANIMATION
45
46 namespace Tizen { namespace Ui { namespace Animations
47 {
48
49 #define TN_CAST(_T)                     static_cast< _TransactionNode* >(_T)
50 #define TN_CONST_CAST(_T)       static_cast< _TransactionNode* >(const_cast< Object* >(_T))
51
52 #define AD_CAST(_AD)            static_cast< _AnimationData* >(_AD)
53 #define AD_CONST_CAST(_AD)      static_cast< _AnimationData* >(const_cast< Object* >(_AD))
54
55 unsigned int
56 _AnimationTime::GetTime(bool loopTime)
57 {
58 #ifdef VE_DEBUG_ANIMATION
59         static unsigned int debug_time = 0;
60
61         debug_time += 20;
62         return debug_time;
63 #else
64         if (likely(loopTime))
65         {
66                 return (unsigned int) (ecore_loop_time_get() * 1000.0f);     // ecore_loop_time_get() returns a value in seconds.
67         }
68
69         return (unsigned int) (ecore_time_get() * 1000.0f);     // ecore_loop_time_get() returns a value in seconds.
70 #endif
71 }
72
73 _AnimationData::_AnimationData(VisualElement& target, const Tizen::Base::String* pName, VisualElementAnimation& animation)
74         : __target(target)
75         , __animation(animation)
76         , __startValue()
77         , __endValue()
78         , __totalDuration(0)
79         , __baseTime(0)
80         , __currentRepeatCount(1)
81         , __keyFrameIndex(0)
82         , __forward(true)
83         , __progress(0.0f)
84         , __status(_STATUS_READY)
85         , __pendingMode(_PENDING_MODE_NONE)
86 {
87         if (pName != null)
88         {
89                 __name = *pName;
90         }
91
92         VisualElementValueAnimation* pValueAnimation = dynamic_cast< VisualElementValueAnimation* >(&__animation);
93         if (pValueAnimation)
94         {
95                 __startValue = pValueAnimation->GetStartValue();
96                 __endValue = pValueAnimation->GetEndValue();
97         }
98
99         long repeatCount = __animation.IsAutoReverseEnabled() ? __animation.GetRepeatCount() * 2 : __animation.GetRepeatCount();
100
101         __totalDuration = __animation.GetDelay() + (__animation.GetDuration() * repeatCount - __animation.GetOffset());
102
103 #ifdef VE_DEBUG_MODULE
104         __tick = 0;
105 #endif
106 }
107
108 _AnimationData::~_AnimationData(void)
109 {
110         delete &__animation;
111 }
112
113 VisualElementAnimation&
114 _AnimationData::GetAnimation(void) const
115 {
116         return __animation;
117 }
118
119 String
120 _AnimationData::GetName(void) const
121 {
122         return __name;
123 }
124
125 VisualElement&
126 _AnimationData::GetTarget(void) const
127 {
128         return __target;
129 }
130
131 bool
132 _AnimationData::IsRemoved(void) const
133 {
134         return (__pendingMode == _PENDING_MODE_REMOVING || __pendingMode == _PENDING_MODE_REMOVE);
135 }
136
137 result
138 _AnimationData::SetBaseTime(unsigned int baseTime)
139 {
140         __baseTime = baseTime;
141
142         if (__status == _STATUS_END)
143         {
144                 // reset for group repeat
145                 __status = _STATUS_READY;
146                 __keyFrameIndex = 0;
147                 __forward = true;
148         }
149
150 #ifdef  VE_DEBUG_MODULE
151         if (_VeDebug::IsDebugEnabled())
152         {
153                 __tick = baseTime;
154         }
155 #endif
156
157         return E_SUCCESS;
158 }
159
160 void
161 _AnimationData::FillValueForProperty(void)
162 {
163         if (__startValue.IsEmpty() || __endValue.IsEmpty())
164         {
165                 VisualElementPropertyAnimation* pPropertyAnimation = dynamic_cast< VisualElementPropertyAnimation* >(&__animation);
166                 if (pPropertyAnimation)
167                 {
168                         Variant currentValue = __target.GetProperty(pPropertyAnimation->GetPropertyName());
169
170                         if (__startValue.IsEmpty())
171                         {
172                                 __startValue = currentValue;
173                         }
174                         else
175                         {
176                                 __endValue = currentValue;
177                         }
178                 }
179         }
180 }
181
182 Variant
183 _AnimationData::CalculateValueByTime(unsigned int currentTime)
184 {
185         long currentRepeatCount = 0;
186         long oldRepeatCount = 0;
187         long repeatCount = 0;
188         long delay = 0;
189         long duration = 0;
190         long offset = 0;
191
192         // Set current Time
193 #ifdef VE_DEBUG_MODULE
194         if (_VeDebug::IsDebugEnabled())
195         {
196                 currentTime = __tick;
197                 __tick += 16;
198         }
199 #endif
200
201         if (__status == _STATUS_END)
202         {
203                 return Variant();
204         }
205
206         if (__status == _STATUS_STOP)
207         {
208                 __status = _STATUS_END;
209
210                 return CalculateValue();
211         }
212
213         // Clac progress
214         if (__animation.GetScaleRatio() > 0.f)
215         {
216                 currentTime = (unsigned int) ((currentTime - __baseTime) / __animation.GetScaleRatio());    // Apply time scale value
217         }
218
219         delay = __animation.GetDelay();
220
221         if (currentTime < (unsigned int)(delay))
222         {
223                 // Not started
224                 __currentRepeatCount = 1;
225                 __forward = true;
226                 __progress = -1.0f;
227
228                 return CalculateValue();
229         }
230
231         offset = __animation.GetOffset();
232         repeatCount = __animation.GetRepeatCount();
233         duration = __animation.GetDuration();
234         if (duration == 0)
235         {
236                 duration = 1;
237                 repeatCount = 1;
238         }
239
240         oldRepeatCount = __currentRepeatCount;
241         currentRepeatCount = ((currentTime - delay + offset) / duration) + 1;
242
243         if (__animation.IsAutoReverseEnabled())
244         {
245                 __currentRepeatCount = (currentRepeatCount + 1) >> 1;
246
247                 __progress = static_cast< float >(currentTime - (delay + duration * (currentRepeatCount - 1) - offset)) / static_cast< float >(duration);
248
249                 if (currentRepeatCount & 0x1)
250                 {
251                         // forward
252                         if (!__forward)
253                         {
254                                 __progress = 0.0f;
255                                 __forward = true;
256                         }
257                 }
258                 else
259                 {
260                         // backward
261                         if (__forward)
262                         {
263                                 __progress = 1.0f;
264                                 __forward = false;
265                         }
266                         else
267                         {
268                                 __progress = 1.0f - __progress;
269                         }
270
271                 }
272         }
273         else
274         {
275                 __currentRepeatCount = currentRepeatCount;
276                 __forward = true;
277
278                 __progress = static_cast< float >(currentTime - (delay + duration * (currentRepeatCount - 1) - offset)) / static_cast< float >(duration);
279         }
280
281         if (__status == _STATUS_READY)
282         {
283                 __status = _STATUS_START;
284
285                 FillValueForProperty();
286         }
287         else if (repeatCount > 0 && currentTime >= __totalDuration) // infinite loop if repeatCount == 0
288         {
289                 // Finished
290                 __currentRepeatCount = repeatCount;
291                 __forward = true;
292                 __progress = (__animation.IsAutoReverseEnabled() ? 0.0f : 1.0f);
293
294                 __status = _STATUS_STOP;
295         }
296         else if (__currentRepeatCount > oldRepeatCount)
297         {
298                 __status = _STATUS_REPEAT;
299
300                 __progress = (__animation.IsAutoReverseEnabled() ? 0.0f : 1.0f);
301         }
302         else
303         {
304                 __status = _STATUS_RUNNING;
305         }
306
307         return CalculateValue();
308 }
309
310 Variant
311 _AnimationData::CalculateValue(void)
312 {
313         float calcProgress = 0.0f;
314         Variant current;
315
316         if (__progress < 0.0f || __progress > 1.0f)
317         {
318                 return current;
319         }
320
321         VisualElementValueAnimation* pValueAnimation = dynamic_cast< VisualElementValueAnimation* >(&__animation);
322
323         // In case of VisualElementAnimation
324         if (pValueAnimation == null)
325         {
326                 return current;
327         }
328
329         const IVisualElementAnimationTimingFunction* pTimingFunction = __animation.GetTimingFunction();
330         SysAssertf(pTimingFunction, "Timing function is null.");
331
332         const IVisualElementAnimationValueInterpolator* pInterpolator = __animation.GetValueInterpolator();
333         SysAssertf(pInterpolator, "Interpolotor is null.");
334
335         _VisualElementAnimationKeyFrame* pKeyFrame = _VisualElementValueAnimationImpl::GetInstance(*pValueAnimation)->GetKeyFrame();
336
337         if (pKeyFrame != null)
338         {
339                 _VariantEx start;
340                 _VariantEx end;
341
342                 int keyFrameCount = pKeyFrame->GetCount();
343                 SysAssertf(keyFrameCount > 0, "The count of key frames is zero.");
344
345                 if (__forward)
346                 {
347                         if (__keyFrameIndex == keyFrameCount)   // last section
348                         {
349                                 _VisualElementAnimationKeyFrameInfo* pFromInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex - 1);
350                                 SysAssertf(pFromInfo, "Index (%d) of key frame is invalid.", __keyFrameIndex - 1);
351
352                                 start = pFromInfo->GetValueEx();
353                                 end = __endValue;
354
355                                 calcProgress = pTimingFunction->CalculateProgress((__progress - pFromInfo->GetTime()) / (1.0f - pFromInfo->GetTime()));
356
357                                 if (_FloatCompare(__progress, 1.0f))
358                                 {
359                                         __keyFrameIndex = 0;
360                                 }
361                         }
362                         else
363                         {
364                                 _VisualElementAnimationKeyFrameInfo* pToInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex);
365                                 SysAssertf(pToInfo, "Index (%d) of key frame is invalid.", __keyFrameIndex);
366
367                                 while (__progress > pToInfo->GetTime())
368                                 {
369                                         __keyFrameIndex++;
370                                         if (__keyFrameIndex == keyFrameCount)
371                                         {
372                                                 break;
373                                         }
374
375                                         pToInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex);
376                                         SysAssertf(pToInfo, "Index (%d) of key frame is invalid.", __keyFrameIndex);
377                                 }
378
379                                 const IVisualElementAnimationTimingFunction* pToTimingFunction = pToInfo->GetTimingFunction();
380                                 if (pToTimingFunction == null)
381                                 {
382                                         pToTimingFunction = pTimingFunction;
383                                 }
384
385                                 if (__keyFrameIndex == 0)  //first section
386                                 {
387                                         start = __startValue;
388                                         end = pToInfo->GetValueEx();
389
390                                         calcProgress = pToTimingFunction->CalculateProgress(__progress / pToInfo->GetTime());
391                                 }
392                                 else if (__keyFrameIndex == keyFrameCount) //last section
393                                 {
394                                         // pToInfo means pFromInfo in last section
395                                         start = pToInfo->GetValueEx();
396                                         end = __endValue;
397
398                                         calcProgress = pTimingFunction->CalculateProgress((__progress - pToInfo->GetTime()) / (1.0f - pToInfo->GetTime()));
399                                 }
400                                 else
401                                 {
402                                         _VisualElementAnimationKeyFrameInfo* pFromInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex - 1);
403                                         SysAssertf(pFromInfo, "Index (%d) of key frame is invalid.", __keyFrameIndex - 1);
404
405                                         start = pFromInfo->GetValueEx();
406                                         end = pToInfo->GetValueEx();
407
408                                         calcProgress = pToTimingFunction->CalculateProgress((__progress - pFromInfo->GetTime()) / (pToInfo->GetTime() - pFromInfo->GetTime()));
409                                 }
410                         }
411                 }
412                 else    //backward
413                 {
414                         if (__keyFrameIndex == 0)   //last section in backward (= first section in forward)
415                         {
416                                 _VisualElementAnimationKeyFrameInfo* pFromInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex);
417                                 SysAssertf(pFromInfo, "Index (%d) of key frame is invalid.", __keyFrameIndex);
418
419                                 const IVisualElementAnimationTimingFunction* pFromTimingFunction = pFromInfo->GetTimingFunction();
420                                 if (pFromTimingFunction == null)
421                                 {
422                                         pFromTimingFunction = pTimingFunction;
423                                 }
424
425                                 start = __startValue;
426                                 end = pFromInfo->GetValueEx();
427
428                                 calcProgress = pFromTimingFunction->CalculateProgress(__progress / pFromInfo->GetTime());
429                         }
430                         else
431                         {
432                                 _VisualElementAnimationKeyFrameInfo* pToInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex - 1);
433                                 SysAssertf(pToInfo, "Index (%d) of key frame is invalid.", __keyFrameIndex - 1);
434
435                                 while (__progress < pToInfo->GetTime())
436                                 {
437                                         __keyFrameIndex--;
438                                         if (__keyFrameIndex == 0)
439                                         {
440                                                 break;
441                                         }
442
443                                         pToInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex - 1);
444                                         SysAssertf(pToInfo, "Index (%d) of key frame is invalid", __keyFrameIndex - 1);
445                                 }
446
447                                 const IVisualElementAnimationTimingFunction* pToTimingFunction = pToInfo->GetTimingFunction();
448                                 if (pToTimingFunction == null)
449                                 {
450                                         pToTimingFunction = pTimingFunction;
451                                 }
452
453                                 if (__keyFrameIndex == 0)   //last section in backward
454                                 {
455                                         start = __startValue;
456                                         end = pToInfo->GetValueEx();
457
458                                         calcProgress = pToTimingFunction->CalculateProgress(__progress / pToInfo->GetTime());
459                                 }
460                                 else if (__keyFrameIndex == keyFrameCount)  //first section in backward (= last section in forward)
461                                 {
462                                         start = pToInfo->GetValueEx();
463                                         end = __endValue;
464
465                                         calcProgress = pTimingFunction->CalculateProgress((__progress - pToInfo->GetTime()) / (1.0f - pToInfo->GetTime()));
466                                 }
467                                 else
468                                 {
469                                         _VisualElementAnimationKeyFrameInfo* pFromInfo = pKeyFrame->GetKeyFrameInfoAt(__keyFrameIndex);
470                                         SysAssertf(pFromInfo, "Index (%d) of key frame is invalid.", __keyFrameIndex);
471
472                                         const IVisualElementAnimationTimingFunction* pFromTimingFunction = pFromInfo->GetTimingFunction();
473                                         if (pFromTimingFunction == null)
474                                         {
475                                                 pFromTimingFunction = pTimingFunction;
476                                         }
477
478                                         start = pToInfo->GetValueEx();
479                                         end = pFromInfo->GetValueEx();
480
481                                         calcProgress = pFromTimingFunction->CalculateProgress((__progress - pToInfo->GetTime()) / (pFromInfo->GetTime() - pToInfo->GetTime()));
482                                 }
483                         }
484                 }
485
486                 if (pInterpolator->Interpolate(calcProgress, start, end, current) != E_SUCCESS)
487                 {
488                         return start;
489                 }
490         }
491         else // no keyframe
492         {
493                 calcProgress = pTimingFunction->CalculateProgress(__progress);
494
495                 if (pInterpolator->Interpolate(calcProgress, __startValue, __endValue, current) != E_SUCCESS)
496                 {
497                         return __startValue;
498                 }
499         }
500
501         return current;
502 }
503
504 void
505 _AnimationData::NotifyAnimationStatus(bool completed)
506 {
507         if (__status == _STATUS_END)
508         {
509                 return;
510         }
511
512         IVisualElementAnimationStatusEventListener* pListener = _VisualElementAnimationImpl::GetInstance(__animation)->GetStatusEventListener();
513         if (pListener == null)
514         {
515                 return;
516         }
517
518         _VisualElementAnimationImpl* pAnimationImpl = _VisualElementAnimationImpl::GetInstance(__animation);
519
520         if (completed == false)
521         {
522                 pListener->OnVisualElementAnimationFinished(__animation, __name, pAnimationImpl->GetEventTarget(), false);
523                 return;
524         }
525
526         switch (__status)
527         {
528         case _AnimationData::_STATUS_START:
529                 pListener->OnVisualElementAnimationStarted(__animation, __name, pAnimationImpl->GetEventTarget());
530                 break;
531
532         case _AnimationData::_STATUS_REPEAT:
533                 pListener->OnVisualElementAnimationRepeated(__animation, __name, pAnimationImpl->GetEventTarget(), __currentRepeatCount);
534                 break;
535
536         case _AnimationData::_STATUS_STOP:
537                 pListener->OnVisualElementAnimationFinished(__animation, __name, pAnimationImpl->GetEventTarget(), true);
538                 break;
539
540         default:
541                 break;
542         }
543 }
544
545 void
546 _AnimationData::NotifyAnimationFinished(bool completed)
547 {
548         if (__status == _STATUS_END)
549         {
550                 return;
551         }
552
553         if (__status != _STATUS_STOP)
554         {
555                 __status = _STATUS_STOP;
556         }
557
558         IVisualElementAnimationStatusEventListener* pListener = _VisualElementAnimationImpl::GetInstance(__animation)->GetStatusEventListener();
559         if (pListener == null)
560         {
561                 return;
562         }
563
564         _VisualElementAnimationImpl* pAnimationImpl = _VisualElementAnimationImpl::GetInstance(__animation);
565
566         pListener->OnVisualElementAnimationFinished(__animation, __name, pAnimationImpl->GetEventTarget(), completed);
567 }
568
569 void
570 _AnimationData::OnTickOccurred(VisualElement& target, const Tizen::Ui::Variant& currentValue)
571 {
572         if (currentValue.IsEmpty() == true)
573         {
574                 return;
575         }
576
577         VisualElementValueAnimation* pValueAnimation = dynamic_cast< VisualElementValueAnimation* >(&__animation);
578
579         if (pValueAnimation != null)
580         {
581                 _VisualElementValueAnimationImpl* pValueAnimationImpl = _VisualElementValueAnimationImpl::GetInstance(*pValueAnimation);
582
583                 pValueAnimationImpl->OnTickOccurred(target, currentValue);
584
585                 IVisualElementAnimationTickEventListener *pTickListener = pValueAnimationImpl->GetTickEventListener();
586
587                 if (pTickListener != null)
588                 {
589                         pTickListener->OnTickOccurred(*pValueAnimation, __name, pValueAnimationImpl->GetEventTarget(), currentValue);
590                 }
591         }
592 }
593
594 static int id = -1;
595
596 // class _TransactionNode
597 _TransactionNode::_TransactionNode(void)
598         : __id(-1)
599         , __pParent(null)
600         , __pRoot(this)
601         , __pDefaultListener(null)
602         , __pListener(null)
603         , __isImplicitAnimationEnabled(true)
604         , __isCommitted(false)
605         , __isReservedRemove(false)
606         , __isInAnimationTick(false)
607         , __status(_STATUS_READY)
608         , __baseTime(0)
609         , __adjustedBaseTime(0)
610         , __currentRepeatCount(1)
611 {
612         ClearLastResult();
613
614         __id = id = (id >= 0xFFFFFF ? 0 : id + 1);
615
616         result r = __children.Construct();
617         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to construct children list.", GetErrorMessage(r));
618
619         r = __pendingAnimations.Construct();
620         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to construct pending list.", GetErrorMessage(r));
621
622         r = __animations.Construct();
623         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to construct animations map.", GetErrorMessage(r));
624 }
625
626 _TransactionNode::_TransactionNode(const _TransactionNode& node)
627         : __id(-1)
628         , __pParent(null)
629         , __pRoot(node.__pRoot)
630         , __pDefaultListener(null)
631         , __pListener(null)
632         , __isImplicitAnimationEnabled(node.__isImplicitAnimationEnabled)
633         , __isCommitted(false)
634         , __isReservedRemove(false)
635         , __isInAnimationTick(false)
636         , __status(_STATUS_READY)
637         , __baseTime(0)
638         , __adjustedBaseTime(0)
639         , __currentRepeatCount(1)
640 {
641         ClearLastResult();
642
643         __id = id = (id >= 0xFFFFFF ? 0 : id + 1);
644
645         result r = __children.Construct();
646         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to construct children list.", GetErrorMessage(r));
647
648         r = __pendingAnimations.Construct();
649         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to construct pending list.", GetErrorMessage(r));
650
651         r = __animations.Construct();
652         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to construct animations map.", GetErrorMessage(r));
653
654         r = CopyAnimationValue(node);
655         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to copy the animation value.", GetErrorMessage(r));
656 }
657
658 _TransactionNode::~_TransactionNode(void)
659 {
660         __children.RemoveAll(true);
661
662         __pendingAnimations.RemoveAll(true);
663
664         RemoveAllAnimations();
665 }
666
667 bool
668 _TransactionNode::Equals(const Object& obj) const
669 {
670         if (this == &obj)
671         {
672                 return true;
673         }
674
675         return false;
676 }
677
678 int
679 _TransactionNode::GetId(void) const
680 {
681         return __id;
682 }
683
684 _TransactionNode*
685 _TransactionNode::GetParent(void) const
686 {
687         return __pParent;
688 }
689
690 result
691 _TransactionNode::SetParent(_TransactionNode& parent)
692 {
693         __pParent = &parent;
694
695         return E_SUCCESS;
696 }
697
698 result
699 _TransactionNode::SetDefaultEventListener(const IAnimationTransactionEventListener* pListener)
700 {
701         __pDefaultListener = const_cast< IAnimationTransactionEventListener* >(pListener);
702
703         return E_SUCCESS;
704 }
705
706 IAnimationTransactionEventListener*
707 _TransactionNode::GetEventListener(void) const
708 {
709         return __pListener;
710 }
711
712 result
713 _TransactionNode::SetEventListener(const IAnimationTransactionEventListener* pListener)
714 {
715         __pListener = const_cast< IAnimationTransactionEventListener* >(pListener);
716
717         return E_SUCCESS;
718 }
719
720 bool
721 _TransactionNode::IsImplicitAnimationEnabled(void) const
722 {
723         return __isImplicitAnimationEnabled;
724 }
725
726 result
727 _TransactionNode::SetImplicitAnimationEnabled(bool enable)
728 {
729         __isImplicitAnimationEnabled = enable;
730
731         return E_SUCCESS;
732 }
733
734 int
735 _TransactionNode::GetChildrenCount(void) const
736 {
737         return __children.GetCount();
738 }
739
740 _TransactionNode*
741 _TransactionNode::GetChild(int transactionId) const
742 {
743         SysTryReturn(NID_UI_ANIM, transactionId > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(s) is used. transactionId = %d", transactionId);
744
745         int childrenCount = GetChildrenCount();
746
747         if (childrenCount <= 0)
748         {
749                 return null;
750         }
751
752         _TransactionNode* pChild = null;
753
754         for (int index = 0; index < childrenCount; index++)
755         {
756                 pChild = TN_CONST_CAST(__children.GetAt(index));
757
758                 if (pChild->GetId() == transactionId)
759                 {
760                         return pChild;
761                 }
762
763                 pChild = pChild->GetChild(transactionId);
764
765                 if (pChild != null)
766                 {
767                         return pChild;
768                 }
769         }
770
771         return null;
772 }
773
774 _TransactionNode*
775 _TransactionNode::GetLastChild(void) const
776 {
777         int index = GetChildrenCount() - 1;
778
779         SysTryReturn(NID_UI_ANIM, index >= 0, null, E_INVALID_OPERATION, "[E_INVALID_OPERATION] This node has no child.");
780
781         return TN_CONST_CAST(__children.GetAt(index));
782 }
783
784 result
785 _TransactionNode::AddChild(_TransactionNode& child)
786 {
787         result r = __children.Add(child);
788         SysTryReturnResult(NID_UI_ANIM, r == E_SUCCESS, r, "Propagating.");
789
790         child.SetParent(*this);
791
792         return E_SUCCESS;
793 }
794
795 void
796 _TransactionNode::RemoveChild(int transactionId)
797 {
798         SysTryReturnVoidResult(NID_UI_ANIM, transactionId > 0, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(s) is used. transactionId = %d", transactionId);
799
800         int childrenCount = GetChildrenCount();
801
802         if (childrenCount <= 0)
803         {
804                 return;
805         }
806
807         _TransactionNode* pChild = null;
808
809         for (int index = 0; index < childrenCount; index++)
810         {
811                 pChild = TN_CAST(__children.GetAt(index));
812
813                 if (pChild->GetId() == transactionId)
814                 {
815                         if (pChild->IsReservedRemove() == false)
816                         {
817                                 pChild->RemoveAll();
818
819                                 pChild->ReservedRemove();
820
821                                 pChild->NotifyTransactionStatus(false);
822
823                                 RemoveChild(*pChild);
824                         }
825                         break;
826                 }
827
828                 pChild->RemoveChild(transactionId);
829         }
830 }
831
832 void
833 _TransactionNode::RemoveChild(_TransactionNode& child)
834 {
835         if (child.IsInAnimationTick())
836         {
837                 child.ReservedRemove();
838         }
839         else
840         {
841                 result r = __children.Remove(child, true);
842
843                 SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to remove child.", GetErrorMessage(r));
844         }
845 }
846
847 void
848 _TransactionNode::RemoveAll(void)       //TODO: rename RemoveAll()
849 {
850         _TransactionNode* pChild = null;
851
852         int childrenCount = GetChildrenCount();
853
854         for (int index = childrenCount-1; index >= 0; index--)
855         {
856                 pChild = TN_CAST(__children.GetAt(index));
857
858                 if (pChild->IsReservedRemove() == false)
859                 {
860                         pChild->RemoveAll();
861
862                         pChild->ReservedRemove(true);
863
864                         pChild->NotifyTransactionStatus(false);
865
866                         RemoveChild(*pChild);
867                 }
868         }
869
870         RemoveAllAnimations();
871 }
872
873 int
874 _TransactionNode::GetAnimationCount(void) const
875 {
876         //TODO: make exactly
877         return __animations.GetCount();
878 }
879
880 _AnimationData*
881 _TransactionNode::GetAnimationDataInPending(VisualElement& target, const String& keyName) const
882 {
883         int pendingCount = __pendingAnimations.GetCount();
884
885         _AnimationData* pAnimationData = null;
886
887         for (int index = 0; index < pendingCount; index++)
888         {
889                 pAnimationData = AD_CONST_CAST(__pendingAnimations.GetAt(index));
890
891                 if (&(pAnimationData->GetTarget()) == &target && pAnimationData->IsRemoved() == false)
892                 {
893                         if (pAnimationData->GetName() == keyName)
894                         {
895                                 return pAnimationData;
896                         }
897                 }
898         }
899
900         return null;
901 }
902
903 _AnimationData*
904 _TransactionNode::GetAnimationDataInPendingByProperty(VisualElement& target, const String& property) const
905 {
906         int pendingCount = __pendingAnimations.GetCount();
907
908         _AnimationData* pAnimationData = null;
909         VisualElementPropertyAnimation* pPropertyAnimation = null;
910
911         for (int index = 0; index < pendingCount; index++)
912         {
913                 pAnimationData = AD_CONST_CAST(__pendingAnimations.GetAt(index));
914
915                 if (&(pAnimationData->GetTarget()) == &target && pAnimationData->IsRemoved() == false)
916                 {
917                         pPropertyAnimation = dynamic_cast< VisualElementPropertyAnimation* >(&(pAnimationData->GetAnimation()));
918
919                         if(pPropertyAnimation != null && pPropertyAnimation->GetPropertyName() == property)
920                         {
921                                 return pAnimationData;
922                         }
923                 }
924         }
925
926         return null;
927 }
928
929 result
930 _TransactionNode::AddAnimationData(_AnimationData& animationData)
931 {
932         result r = E_SUCCESS;
933
934         ArrayList* pAnimationList = null;
935         VisualElement* pTarget = &(animationData.GetTarget());
936
937         __animations.GetValue(pTarget, pAnimationList);
938
939         if (pAnimationList == null)
940         {
941                 pAnimationList = new (std::nothrow) ArrayList();
942                 SysTryReturnResult(NID_UI_ANIM, pAnimationList != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
943
944                 r = pAnimationList->Construct();
945                 SysTryReturnResult(NID_UI_ANIM, r == E_SUCCESS, r, "Failed to construct animation list.");
946
947                 __animations.Add(pTarget, pAnimationList);
948         }
949
950         // base time for root
951         animationData.SetBaseTime(_AnimationTime::GetTime());
952         animationData.SetPendingMode(_AnimationData::_PENDING_MODE_NONE);
953
954         return pAnimationList->Add(animationData);
955 }
956
957 void
958 _TransactionNode::RemoveAnimationData(_AnimationData& animationData)
959 {
960         ArrayList* pAnimationList = null;
961         VisualElement* pTarget = &(animationData.GetTarget());
962
963         __animations.GetValue(pTarget, pAnimationList);
964
965         if (pAnimationList == null)
966         {
967                 return;
968         }
969
970         pAnimationList->Remove(animationData, true);
971
972         if (pAnimationList->GetCount() <= 0)
973         {
974                 __animations.Remove(pTarget);
975
976                 delete pAnimationList;
977         }
978 }
979
980 result
981 _TransactionNode::SetAnimationDataAsPending(_AnimationData& animationData, bool remove, bool completed)
982 {
983         result r = E_SUCCESS;
984
985         if (remove == true)
986         {
987                 if (animationData.IsRemoved())
988                 {
989                         return E_SUCCESS;
990                 }
991
992                 if (animationData.GetPendingMode() == _AnimationData::_PENDING_MODE_NONE)
993                 {
994                         r = __pendingAnimations.Add(animationData);
995                 }
996
997                 animationData.SetPendingMode(_AnimationData::_PENDING_MODE_REMOVING);
998
999                 animationData.NotifyAnimationFinished(completed);
1000
1001                 animationData.SetPendingMode(_AnimationData::_PENDING_MODE_REMOVE);
1002         }
1003         else
1004         {
1005                 animationData.SetPendingMode(_AnimationData::_PENDING_MODE_ADD);
1006
1007                 r = __pendingAnimations.Add(animationData);
1008         }
1009
1010         return r;
1011 }
1012
1013 result
1014 _TransactionNode::AddAnimation(VisualElement& target, const String* pKeyName, VisualElementAnimation& animation)
1015 {
1016         result r = E_SUCCESS;
1017
1018         _AnimationData* pAnimationData = new (std::nothrow) _AnimationData(target, pKeyName, animation);
1019         SysTryReturnResult(NID_UI_ANIM, pAnimationData != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1020
1021         if (__isInAnimationTick == true)
1022         {
1023                 r = SetAnimationDataAsPending(*pAnimationData, false);
1024         }
1025         else
1026         {
1027                 r = AddAnimationData(*pAnimationData);
1028         }
1029
1030         if (r != E_SUCCESS)
1031         {
1032                 delete pAnimationData;
1033
1034                 return r;
1035         }
1036
1037         return E_SUCCESS;
1038 }
1039
1040 result
1041 _TransactionNode::RemoveAnimation(VisualElement& target, const String& keyName)
1042 {
1043         if (GetAnimationCount() <= 0)
1044         {
1045                 return E_OBJ_NOT_FOUND;
1046         }
1047
1048         result r = E_OBJ_NOT_FOUND;
1049
1050         _AnimationData* pAnimationData = GetAnimationDataInPending(target, keyName);
1051
1052         if (pAnimationData != null)
1053         {
1054                 r = SetAnimationDataAsPending(*pAnimationData, true, false);
1055                 SysTryReturnResult(NID_UI_ANIM, r == E_SUCCESS, r, "Failed to add to pending list.");
1056
1057                 return E_SUCCESS;
1058         }
1059
1060         ArrayList* pAnimationList = null;
1061
1062         __animations.GetValue(&target, pAnimationList);
1063
1064         if (pAnimationList == null)
1065         {
1066                 return E_OBJ_NOT_FOUND;
1067         }
1068
1069         int animationCount = pAnimationList->GetCount();
1070
1071         for (int index = 0; index < animationCount; index++)
1072         {
1073                 pAnimationData = AD_CAST(pAnimationList->GetAt(index));
1074
1075                 if (pAnimationData->IsRemoved() == false)
1076                 {
1077                         if (pAnimationData->GetName() == keyName)
1078                         {
1079                                 r = SetAnimationDataAsPending(*pAnimationData, true, false);
1080                                 SysTryReturnResult(NID_UI_ANIM, r == E_SUCCESS, r, "Failed to add to pending list.");
1081
1082                                 break;
1083                         }
1084                 }
1085         }
1086
1087         ProcessPendingAnimations();
1088
1089         return r;
1090 }
1091
1092 result
1093 _TransactionNode::RemoveChildrenAnimation(VisualElement& target, const String& keyName)
1094 {
1095         SysTryReturnResult(NID_UI_ANIM, keyName.IsEmpty() == false, E_OBJ_NOT_FOUND, "keyName is empty.");
1096
1097         if (RemoveAnimation(target, keyName) == E_SUCCESS)
1098         {
1099                 return E_SUCCESS;
1100         }
1101
1102         int childrenCount = GetChildrenCount();
1103
1104         if (childrenCount <= 0)
1105         {
1106                 return E_OBJ_NOT_FOUND;
1107         }
1108
1109         _TransactionNode* pChild = null;
1110         _AnimationGroupNode* pGroup = null;
1111
1112         for (int index = 0; index < childrenCount; index++)
1113         {
1114                 pChild = TN_CAST(__children.GetAt(index));
1115                 pGroup = dynamic_cast< _AnimationGroupNode* >(pChild);
1116
1117                 if (pGroup != null && pGroup->IsEqual(target, keyName))
1118                 {
1119                         pChild->NotifyTransactionStatus(false);
1120
1121                         RemoveChild(*pChild);
1122                         return E_SUCCESS;
1123                 }
1124                 else if (pChild->RemoveChildrenAnimation(target, keyName) == E_SUCCESS)
1125                 {
1126                         return E_SUCCESS;
1127                 }
1128         }
1129
1130         return E_OBJ_NOT_FOUND;
1131 }
1132
1133 void
1134 _TransactionNode::RemoveAnimationByProperty(VisualElement& target, const String& property)
1135 {
1136         if (GetAnimationCount() <= 0)
1137         {
1138                 return;
1139         }
1140
1141         result r = E_OBJ_NOT_FOUND;
1142
1143         _AnimationData* pAnimationData = GetAnimationDataInPendingByProperty(target, property);
1144
1145         if (pAnimationData != null)
1146         {
1147                 r = SetAnimationDataAsPending(*pAnimationData, true, false);
1148                 SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to add to pending list.", GetErrorMessage(r));
1149
1150                 return;
1151         }
1152
1153         ArrayList* pAnimationList = null;
1154
1155         __animations.GetValue(&target, pAnimationList);
1156
1157         if (pAnimationList == null)
1158         {
1159                 return;
1160         }
1161
1162         VisualElementPropertyAnimation* pPropertyAnimation = null;
1163
1164         int animationCount = pAnimationList->GetCount();
1165
1166         for (int index = 0; index < animationCount; index++)
1167         {
1168                 pAnimationData = AD_CAST(pAnimationList->GetAt(index));
1169
1170                 if (pAnimationData->IsRemoved() == false)
1171                 {
1172                         pPropertyAnimation = dynamic_cast< VisualElementPropertyAnimation* >(&(pAnimationData->GetAnimation()));
1173
1174                         if (pPropertyAnimation != null && pPropertyAnimation->GetPropertyName() == property)
1175                         {
1176                                 r = SetAnimationDataAsPending(*pAnimationData, true, false);
1177                                 SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to add to pending list.", GetErrorMessage(r));
1178
1179                                 break;
1180                         }
1181                 }
1182         }
1183
1184         ProcessPendingAnimations();
1185 }
1186
1187 void
1188 _TransactionNode::RemoveChildrenAnimationByProperty(VisualElement& target, const String& property)
1189 {
1190         RemoveAnimationByProperty(target, property);
1191
1192         int childrenCount = GetChildrenCount();
1193
1194         if (childrenCount <= 0)
1195         {
1196                 return;
1197         }
1198
1199         _TransactionNode* pChild = null;
1200
1201         for (int index = 0; index < childrenCount; index++)
1202         {
1203                 pChild = TN_CAST(__children.GetAt(index));
1204
1205                 pChild->RemoveChildrenAnimationByProperty(target, property);
1206         }
1207 }
1208
1209 void
1210 _TransactionNode::RemoveAllAnimations(void)
1211 {
1212         if (GetAnimationCount() <= 0)
1213         {
1214                 return;
1215         }
1216
1217         // use key list because map item would be removed
1218         IListT<VisualElement*>* pKeyList = __animations.GetKeysN();
1219         SysTryReturnVoidResult(NID_UI_ANIM, pKeyList != null, E_SYSTEM, "[E_SYSTEM] Failed to add to animation.");
1220
1221         VisualElement* pTarget = null;
1222
1223         for (int index = 0; index < pKeyList->GetCount(); index++)
1224         {
1225                 pKeyList->GetAt(index, pTarget);
1226
1227                 if (pTarget != null)
1228                 {
1229                         RemoveAllAnimations(*pTarget);
1230                 }
1231         }
1232
1233         delete pKeyList;
1234
1235         __animations.RemoveAll();
1236 }
1237
1238 void
1239 _TransactionNode::RemoveAllAnimations(VisualElement& target)
1240 {
1241         if (GetAnimationCount() <= 0)
1242         {
1243                 return;
1244         }
1245
1246         ArrayList* pAnimationList = null;
1247
1248         __animations.GetValue(&target, pAnimationList);
1249
1250         if (pAnimationList == null)
1251         {
1252                 return;
1253         }
1254
1255         result r = E_SUCCESS;
1256         _AnimationData* pAnimationData = null;
1257
1258         int animationCount = pAnimationList->GetCount();
1259
1260         for (int index = 0; index < animationCount; index++)
1261         {
1262                 pAnimationData = AD_CAST(pAnimationList->GetAt(index));
1263
1264                 r = SetAnimationDataAsPending(*pAnimationData, true, false);
1265                 SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to add to pending list.", GetErrorMessage(r));
1266         }
1267
1268         ProcessPendingAnimations();
1269 }
1270
1271 void
1272 _TransactionNode::RemoveChildrenAllAnimations(VisualElement& target)
1273 {
1274         RemoveAllAnimations(target);
1275
1276         int childrenCount = GetChildrenCount();
1277
1278         if (childrenCount <= 0)
1279         {
1280                 return;
1281         }
1282
1283         _TransactionNode* pChild = null;
1284
1285         for (int index = childrenCount-1; index >= 0; index--)
1286         {
1287                 pChild = TN_CAST(__children.GetAt(index));
1288
1289                 pChild->RemoveChildrenAllAnimations(target);
1290
1291                 if (pChild->IsReservedRemove() == false && pChild->IsCommitted() == true && pChild->IsEmpty() == true)
1292                 {
1293                         pChild->NotifyTransactionStatus(false);
1294
1295                         RemoveChild(*pChild);
1296                 }
1297         }
1298 }
1299
1300 const VisualElementAnimation*
1301 _TransactionNode::GetAnimation(VisualElement& target, const String& keyName) const
1302 {
1303         if (GetAnimationCount() <= 0)
1304         {
1305                 return null;
1306         }
1307
1308         _AnimationData* pAnimationData = GetAnimationDataInPending(target, keyName);
1309
1310         if (pAnimationData != null)
1311         {
1312                 return &(pAnimationData->GetAnimation());
1313         }
1314
1315         ArrayList* pAnimationList = null;
1316
1317         __animations.GetValue(&target, pAnimationList);
1318
1319         if (pAnimationList == null)
1320         {
1321                 return null;
1322         }
1323
1324         int animationCount = pAnimationList->GetCount();
1325
1326         for (int index = 0; index < animationCount; index++)
1327         {
1328                 pAnimationData = AD_CAST(pAnimationList->GetAt(index));
1329
1330                 if (pAnimationData->IsRemoved() == false)
1331                 {
1332                         if (pAnimationData->GetName() == keyName)
1333                         {
1334                                 return &(pAnimationData->GetAnimation());
1335                         }
1336                 }
1337         }
1338
1339         return null;
1340 }
1341
1342 const VisualElementAnimation*
1343 _TransactionNode::GetChildrenAnimation(VisualElement& target, const String& keyName) const
1344 {
1345         SysTryReturn(NID_UI_ANIM, keyName.IsEmpty() == false, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] keyName is empty.");
1346
1347         const VisualElementAnimation* pAnimation = GetAnimation(target, keyName);
1348
1349         if (pAnimation != null)
1350         {
1351                 return pAnimation;
1352         }
1353
1354         int childrenCount = GetChildrenCount();
1355
1356         if (childrenCount <= 0)
1357         {
1358                 return null;
1359         }
1360
1361         _TransactionNode* pChild = null;
1362         _AnimationGroupNode* pGroup = null;
1363
1364         for (int index = 0; index < childrenCount; index++)
1365         {
1366                 pChild = TN_CONST_CAST(__children.GetAt(index));
1367                 pGroup = dynamic_cast< _AnimationGroupNode* >(pChild);
1368
1369                 if (pGroup != null && pGroup->IsEqual(target, keyName))
1370                 {
1371                         pAnimation = &(pGroup->GetAnimation());
1372                 }
1373                 else
1374                 {
1375                         pAnimation = pChild->GetChildrenAnimation(target, keyName);
1376                 }
1377
1378                 if (pAnimation != null)
1379                 {
1380                         return pAnimation;
1381                 }
1382         }
1383
1384         return null;
1385 }
1386
1387 const VisualElementAnimation*
1388 _TransactionNode::GetAnimationByProperty(VisualElement& target, const String& property) const
1389 {
1390         if (GetAnimationCount() <= 0)
1391         {
1392                 return null;
1393         }
1394
1395         _AnimationData* pAnimationData = GetAnimationDataInPendingByProperty(target, property);
1396
1397         if (pAnimationData != null)
1398         {
1399                 return &(pAnimationData->GetAnimation());
1400         }
1401
1402         ArrayList* pAnimationList = null;
1403
1404         __animations.GetValue(&target, pAnimationList);
1405
1406         if (pAnimationList == null)
1407         {
1408                 return null;
1409         }
1410
1411         const VisualElementPropertyAnimation* pPropertyAnimation = null;
1412
1413         int animationCount = pAnimationList->GetCount();
1414
1415         for (int index = 0; index < animationCount; index++)
1416         {
1417                 pAnimationData = AD_CAST(pAnimationList->GetAt(index));
1418
1419                 if (pAnimationData->IsRemoved() == false)
1420                 {
1421                         pPropertyAnimation = dynamic_cast< VisualElementPropertyAnimation* >(&(pAnimationData->GetAnimation()));
1422
1423                         if (pPropertyAnimation != null && pPropertyAnimation->GetPropertyName() == property)
1424                         {
1425                                 break;
1426                         }
1427                 }
1428         }
1429
1430         return pPropertyAnimation;
1431 }
1432
1433 const VisualElementAnimation*
1434 _TransactionNode::GetChildrenAnimationByProperty(VisualElement& target, const String& property) const
1435 {
1436         const VisualElementAnimation* pAnimation = GetAnimationByProperty(target, property);
1437
1438         if (pAnimation != null)
1439         {
1440                 return pAnimation;
1441         }
1442
1443         int childrenCount = GetChildrenCount();
1444
1445         if (childrenCount <= 0)
1446         {
1447                 return null;
1448         }
1449
1450         _TransactionNode* pChild = null;
1451
1452         for (int index = 0; index < childrenCount; index++)
1453         {
1454                 pChild = TN_CONST_CAST(__children.GetAt(index));
1455
1456                 pAnimation = pChild->GetChildrenAnimationByProperty(target, property);
1457
1458                 if (pAnimation != null)
1459                 {
1460                         break;
1461                 }
1462         }
1463
1464         return pAnimation;
1465 }
1466
1467 void
1468 _TransactionNode::SetBaseTime(unsigned int baseTime)
1469 {
1470         if (GetAnimationCount() <= 0)
1471         {
1472                 return;
1473         }
1474
1475         IMapEnumeratorT<VisualElement*, ArrayList*>* pMapEnum = __animations.GetMapEnumeratorN();
1476
1477         ArrayList* pAnimationList = null;
1478         _AnimationData* pAnimationData = null;
1479
1480         while (pMapEnum->MoveNext() == E_SUCCESS)
1481         {
1482                 pMapEnum->GetValue(pAnimationList);
1483
1484                 if (pAnimationList == null)
1485                 {
1486                         continue;
1487                 }
1488
1489                 int animationCount = pAnimationList->GetCount();
1490
1491                 for (int index = 0; index < animationCount; index++)
1492                 {
1493                         pAnimationData = AD_CAST(pAnimationList->GetAt(index));
1494
1495                         pAnimationData->SetBaseTime(baseTime);
1496                 }
1497         }
1498
1499         delete pMapEnum;
1500 }
1501
1502 void
1503 _TransactionNode::SetChildrenBaseTime(unsigned int baseTime, bool self)
1504 {
1505         if (self == true)
1506         {
1507                 __baseTime = baseTime;
1508                 __adjustedBaseTime = __baseTime;
1509
1510                 if (__status == _STATUS_END)
1511                 {
1512                         __status = _STATUS_READY;
1513                 }
1514         }
1515
1516         SetBaseTime(baseTime);
1517
1518         int childrenCount = GetChildrenCount();
1519
1520         if (childrenCount <= 0)
1521         {
1522                 return;
1523         }
1524
1525         _TransactionNode* pChild = null;
1526
1527         for (int index = 0; index < childrenCount; index++)
1528         {
1529                 pChild = TN_CAST(__children.GetAt(index));
1530
1531                 pChild->SetChildrenBaseTime(baseTime, true);
1532         }
1533 }
1534
1535 void
1536 _TransactionNode::Commit(void)
1537 {
1538         __isCommitted = true;
1539 }
1540
1541 bool
1542 _TransactionNode::IsCommitted(bool ancestors) const
1543 {
1544         if (ancestors == true)
1545         {
1546                 if (__isCommitted == false)
1547                 {
1548                         return __isCommitted;
1549                 }
1550
1551                 bool isCommitted = true;
1552
1553                 if (__pParent != null)
1554                 {
1555                         isCommitted = __pParent->IsCommitted();
1556                 }
1557
1558                 return (isCommitted && __isCommitted);
1559         }
1560
1561         return __isCommitted;
1562 }
1563
1564 bool
1565 _TransactionNode::IsEmpty(void) const
1566 {
1567         return (GetAnimationCount() <= 0 && GetChildrenCount() <= 0);
1568 }
1569
1570 bool
1571 _TransactionNode::IsRunning(void) const
1572 {
1573         return (__status > _STATUS_READY && __status < _STATUS_STOP);
1574 }
1575
1576 void
1577 _TransactionNode::ReservedRemove(bool remove)
1578 {
1579         __isReservedRemove = remove;
1580 }
1581
1582 bool
1583 _TransactionNode::IsReservedRemove(void) const
1584 {
1585         return __isReservedRemove;
1586 }
1587
1588 bool
1589 _TransactionNode::IsRemovable(void) const
1590 {
1591         return true;
1592 }
1593
1594 bool
1595 _TransactionNode::IsInAnimationTick(void)
1596 {
1597         if (__isInAnimationTick == true)
1598         {
1599                 return true;
1600         }
1601
1602         int childrenCount = GetChildrenCount();
1603
1604         if (childrenCount <= 0)
1605         {
1606                 return false;
1607         }
1608
1609         _TransactionNode* pChild = null;
1610
1611         for (int index = 0; index < childrenCount; index++)
1612         {
1613                 pChild = TN_CAST(__children.GetAt(index));
1614
1615                 if (pChild->IsInAnimationTick() == true)
1616                 {
1617                         return true;
1618                 }
1619         }
1620
1621         return false;
1622 }
1623
1624 void
1625 _TransactionNode::CalculateProgress(unsigned int currentTime)
1626 {
1627         if (__status == _STATUS_READY)
1628         {
1629                 __status = _STATUS_START;
1630         }
1631         else
1632         {
1633                 __status = _STATUS_RUNNING;
1634         }
1635 }
1636
1637 void
1638 _TransactionNode::NotifyTransactionStatus(bool completed)
1639 {
1640         if (__isCommitted == false)
1641         {
1642                 return;
1643         }
1644
1645         IAnimationTransactionEventListener* pListener = null;
1646
1647         pListener = (__pListener != null) ? __pListener : __pDefaultListener;
1648
1649         // root transaction doesn't has default listener
1650         if (pListener == null)
1651         {
1652                 return;
1653         }
1654
1655         if (completed == false)
1656         {
1657                 pListener->OnAnimationTransactionStopped(__id);
1658                 return;
1659         }
1660
1661         switch (__status)
1662         {
1663         case _STATUS_START:
1664                 pListener->OnAnimationTransactionStarted(__id);
1665                 break;
1666
1667         case _STATUS_STOP:
1668                 pListener->OnAnimationTransactionFinished(__id);
1669                 break;
1670
1671         default:
1672                 break;
1673         }
1674 }
1675
1676 bool
1677 _TransactionNode::RemoveAnimationByDuplicatedProperty(_AnimationData& animationData)
1678 {
1679         VisualElementPropertyAnimation* pPropertyAnimation = dynamic_cast< VisualElementPropertyAnimation* >(&(animationData.GetAnimation()));
1680
1681         if (pPropertyAnimation == null)
1682         {
1683                 return true;
1684         }
1685
1686         VisualElement* pTarget = &(animationData.GetTarget());
1687
1688         ArrayList* pAnimationList = null;
1689
1690         __animations.GetValue(pTarget, pAnimationList);
1691
1692         if (pAnimationList != null)
1693         {
1694                 _AnimationData* pRemoveAnimationData = null;
1695                 VisualElementPropertyAnimation* pRemovePropertyAnimation = null;
1696
1697                 int animationCount = pAnimationList->GetCount();
1698
1699                 for (int index = 0; index < animationCount; index++)
1700                 {
1701                         pRemoveAnimationData = AD_CAST(pAnimationList->GetAt(index));
1702
1703                         if (&animationData == pRemoveAnimationData)
1704                         {
1705                                 return true;
1706                         }
1707
1708                         pRemovePropertyAnimation = dynamic_cast< VisualElementPropertyAnimation* >(&(pRemoveAnimationData->GetAnimation()));
1709
1710                         if (pRemovePropertyAnimation && pRemovePropertyAnimation->GetPropertyName() == pPropertyAnimation->GetPropertyName())
1711                         {
1712                                 result r = SetAnimationDataAsPending(*pRemoveAnimationData, true, false);
1713                                 SysTryReturn(NID_UI_ANIM, r == E_SUCCESS, r, false, "[%s] Failed to add to pending list.", GetErrorMessage(r));
1714
1715                                 //TODO: refactoring for group
1716                                 if (IsRemovable() == false && pRemoveAnimationData->GetStatus() != _AnimationData::_STATUS_READY)
1717                                 {
1718                                         pRemoveAnimationData->SetStatus(_AnimationData::_STATUS_END);
1719                                         pRemoveAnimationData->SetPendingMode(_AnimationData::_PENDING_MODE_NONE);
1720                                         __pendingAnimations.Remove(*pRemoveAnimationData, false);
1721                                 }
1722                         }
1723                 }
1724         }
1725
1726         int childrenCount = GetChildrenCount();
1727
1728         if (childrenCount <= 0)
1729         {
1730                 return false;
1731         }
1732
1733         _TransactionNode* pChild = null;
1734
1735         for (int index = 0; index < childrenCount; index++)
1736         {
1737                 pChild = TN_CAST(__children.GetAt(index));
1738
1739                 if (pChild->RemoveAnimationByDuplicatedProperty(animationData))
1740                 {
1741                         return true;
1742                 }
1743         }
1744
1745         return false;
1746 }
1747
1748 void
1749 _TransactionNode::ProcessPendingAnimations(void)
1750 {
1751         if (__isInAnimationTick == true)
1752         {
1753                 return;
1754         }
1755
1756         if (__pendingAnimations.GetCount() <= 0)
1757         {
1758                 return;
1759         }
1760
1761         _AnimationData* pAnimationData = null;
1762         int pendingAnimationCount = __pendingAnimations.GetCount();
1763
1764         for (int index = 0; index < pendingAnimationCount; index++)
1765         {
1766                 pAnimationData = AD_CAST(__pendingAnimations.GetAt(index));
1767
1768                 switch(pAnimationData->GetPendingMode())
1769                 {
1770                 case _AnimationData::_PENDING_MODE_ADD:
1771
1772                         if (AddAnimationData(*pAnimationData) != E_SUCCESS)
1773                         {
1774                                 delete pAnimationData;
1775                         }
1776
1777                 break;
1778
1779                 case _AnimationData::_PENDING_MODE_REMOVE:
1780
1781                         RemoveAnimationData(*pAnimationData);
1782                         break;
1783
1784                 default:
1785                         break;
1786                 }
1787         }
1788
1789         __pendingAnimations.RemoveAll(false);
1790 }
1791
1792 void
1793 _TransactionNode::ProcessAnimationTick(unsigned int tick)
1794 {
1795         if (__isCommitted == false)
1796         {
1797                 return;
1798         }
1799
1800         if (__baseTime > tick) // this node is added in animation tick
1801         {
1802                 return;
1803         }
1804
1805         CalculateProgress(tick);
1806
1807         if (__status == _STATUS_READY)
1808         {
1809                 return;
1810         }
1811
1812         if (__status != _STATUS_STOP)
1813         {
1814                 NotifyTransactionStatus(true);
1815         }
1816
1817         if (IsReservedRemove() == true)
1818         {
1819                 return;
1820         }
1821
1822         OnAnimationTick(tick);
1823
1824         _TransactionNode* pChild = null;
1825
1826         for (int index = 0; index < GetChildrenCount(); index++)
1827         {
1828                 pChild = TN_CAST(__children.GetAt(index));
1829
1830                 if (pChild->IsReservedRemove())
1831                 {
1832                         RemoveChild(*pChild);
1833                         index--;
1834
1835                         continue;
1836                 }
1837
1838                 pChild->ProcessAnimationTick(tick);
1839
1840                 if (pChild->__status == _STATUS_STOP)
1841                 {
1842                         pChild->ReservedRemove();
1843
1844                         pChild->NotifyTransactionStatus(true);
1845
1846                         if (pChild->IsRemovable())      // only nested group
1847                         {
1848                                 RemoveChild(*pChild);
1849                                 index--;
1850                         }
1851                         else
1852                         {
1853                                 pChild->ReservedRemove(false);
1854                         }
1855                 }
1856         }
1857
1858         if (IsEmpty() == true)
1859         {
1860                 __status = _STATUS_STOP;
1861         }
1862 }
1863
1864 void
1865 _TransactionNode::OnAnimationTick(unsigned int tick)
1866 {
1867         if (GetAnimationCount() <= 0)
1868         {
1869                 return;
1870         }
1871
1872         __isInAnimationTick = true;
1873
1874         IMapEnumeratorT<VisualElement*, Tizen::Base::Collection::ArrayList*>* pMapEnum = __animations.GetMapEnumeratorN();
1875         SysTryReturnVoidResult(NID_UI_ANIM, (pMapEnum != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1876
1877         VisualElement* pTarget = null;
1878         ArrayList* pAnimationList = null;
1879         _AnimationData* pAnimationData = null;
1880
1881         while (pMapEnum->MoveNext() == E_SUCCESS)
1882         {
1883                 pMapEnum->GetKey(pTarget);      //TODO: remove
1884                 pMapEnum->GetValue(pAnimationList);
1885
1886                 if (pTarget == null || pAnimationList == null)
1887                 {
1888                         continue;
1889                 }
1890
1891                 int animationCount = pAnimationList->GetCount();
1892
1893                 for (int index = 0; index < animationCount; index++)
1894                 {
1895                         pAnimationData = AD_CAST(pAnimationList->GetAt(index));
1896
1897                         // Send finish notification
1898                         if (pAnimationData->GetStatus() == _AnimationData::_STATUS_STOP)
1899                         {
1900                                 SetAnimationDataAsPending(*pAnimationData, true, true);
1901
1902                                 //TODO: refactoring for group
1903                                 if (IsRemovable() == false)
1904                                 {
1905                                         pAnimationData->SetPendingMode(_AnimationData::_PENDING_MODE_NONE);
1906                                         __pendingAnimations.Remove(*pAnimationData, false);
1907                                 }
1908                         }
1909
1910                         if (pAnimationData->IsRemoved())
1911                         {
1912                                 continue;
1913                         }
1914
1915                         Variant currentValue = pAnimationData->CalculateValueByTime(tick);
1916
1917                         // check same property animation
1918                         if (pAnimationData->GetStatus() == _AnimationData::_STATUS_START)
1919                         {
1920                                 __pRoot->RemoveAnimationByDuplicatedProperty(*pAnimationData);
1921                         }
1922
1923                         // Send start, repeat notification
1924                         if (pAnimationData->GetStatus() != _AnimationData::_STATUS_STOP)
1925                         {
1926                                 pAnimationData->NotifyAnimationStatus(true);
1927                         }
1928
1929                         pAnimationData->OnTickOccurred(*pTarget, currentValue);
1930                 }
1931         }
1932
1933         delete pMapEnum;
1934
1935         __isInAnimationTick = false;
1936
1937         ProcessPendingAnimations();
1938 }
1939
1940 _AnimationGroupNode::_AnimationGroupNode(VisualElement& target, const Tizen::Base::String* pName, VisualElementAnimation& animation)
1941         : _TransactionNode()
1942         , __target(target)
1943         , __animation(animation)
1944         , __deleteAnimation(false)
1945         , __totalDuration(0)
1946         , __progress(0.0f)
1947 {
1948         if (pName != null)
1949         {
1950                 __name = *pName;
1951         }
1952
1953         _VisualElementAnimationImpl* pAnimationImpl = _VisualElementAnimationImpl::GetInstance(animation);
1954
1955         result r = CopyAnimationValue(*pAnimationImpl);
1956         SysTryReturnVoidResult(NID_UI_ANIM, r == E_SUCCESS, r, "[%s] Failed to copy the animation value.", GetErrorMessage(r));
1957
1958         // __pAnimation->GetRepeatCount() == 0 infinite
1959         __totalDuration = __animation.GetDelay() + (__animation.GetDuration() * __animation.GetRepeatCount()) - __animation.GetOffset();
1960
1961         if (GetDuration() == 0)
1962         {
1963                 SetDuration(1);
1964                 SetRepeatCount(1);
1965         }
1966
1967 #ifdef VE_DEBUG_MODULE
1968         __tick = 0;
1969 #endif
1970 }
1971
1972 _AnimationGroupNode::~_AnimationGroupNode(void)
1973 {
1974         if (__deleteAnimation == true)
1975         {
1976                 delete &__animation;
1977         }
1978 }
1979
1980 VisualElementAnimation&
1981 _AnimationGroupNode::GetAnimation(void) const
1982 {
1983         return __animation;
1984 }
1985
1986 bool
1987 _AnimationGroupNode::IsEqual(VisualElement& target, const Tizen::Base::String& keyName) const
1988 {
1989         return (&__target == &target && __name == keyName);
1990 }
1991
1992 void
1993 _AnimationGroupNode::Commit(void)
1994 {
1995         __isCommitted = true;
1996
1997         if (dynamic_cast< _AnimationGroupNode* > (__pParent) == null)
1998         {
1999                 __deleteAnimation = true;
2000         }
2001 }
2002
2003 bool
2004 _AnimationGroupNode::IsRemovable(void) const
2005 {
2006         return (__pParent->IsRemovable() && __currentRepeatCount == GetRepeatCount());
2007 }
2008
2009 void
2010 _AnimationGroupNode::CalculateProgress(unsigned int currentTime)
2011 {
2012         long oldRepeatCount = 0;
2013         long repeatCount = 0;
2014         long delay = 0;
2015         long duration = 0;
2016         long offset = 0;
2017
2018         // Set current Time
2019 #ifdef VE_DEBUG_MODULE
2020         if (_VeDebug::IsDebugEnabled())
2021         {
2022                 __tick += 16;
2023         }
2024 #endif
2025
2026         if (__status == _STATUS_END)
2027         {
2028                 return;
2029         }
2030
2031         if (__status == _STATUS_STOP)
2032         {
2033                 __status = _STATUS_END;
2034
2035                 return;
2036         }
2037
2038         if (GetScaleRatio() > 0.f)
2039         {
2040                 currentTime = (unsigned int) ((currentTime - __baseTime) / GetScaleRatio());     // Apply time scale value
2041         }
2042
2043         delay = GetDelay();
2044
2045         if (currentTime < (unsigned int)(delay))
2046         {
2047                 // Not started
2048                 __currentRepeatCount = 1;
2049                 __progress = -1.0f;
2050
2051                 return;
2052         }
2053
2054         offset = __animation.GetOffset();
2055         repeatCount = __animation.GetRepeatCount();
2056         duration = __animation.GetDuration();
2057         if (duration == 0)
2058         {
2059                 duration = 1;
2060                 repeatCount = 1;
2061         }
2062
2063         oldRepeatCount = __currentRepeatCount;
2064         __currentRepeatCount = ((currentTime - delay + offset) / duration) + 1;
2065
2066         __progress = static_cast< float >(currentTime - (delay + duration * (__currentRepeatCount - 1) - offset)) / static_cast< float >(duration);
2067
2068         if (__status == _STATUS_READY)
2069         {
2070                 __status = _STATUS_START;
2071                 __adjustedBaseTime = delay - offset; // __currentRepeatCount is always 1
2072
2073                 SetChildrenBaseTime(__baseTime + __adjustedBaseTime, false);
2074         }
2075         else if (repeatCount > 0 && currentTime >= __totalDuration) // infinite loop if repeatCount == 0
2076         {
2077                 __currentRepeatCount = repeatCount;
2078                 __progress = 1.0f;
2079
2080                 __status = _STATUS_STOP;
2081         }
2082         else if (__currentRepeatCount > oldRepeatCount)
2083         {
2084                 __status = _STATUS_REPEAT;
2085                 __adjustedBaseTime = delay + duration * (__currentRepeatCount - 1) - offset;
2086
2087                 SetChildrenBaseTime(__baseTime + __adjustedBaseTime, false);
2088         }
2089         else
2090         {
2091                 __status = _STATUS_RUNNING;
2092         }
2093 }
2094
2095 void
2096 _AnimationGroupNode::NotifyTransactionStatus(bool completed)
2097 {
2098         if (__status == _STATUS_END)
2099         {
2100                 return;
2101         }
2102         if (__isCommitted == false)
2103         {
2104                 return;
2105         }
2106
2107         _VisualElementAnimationImpl* pAnimationImpl = _VisualElementAnimationImpl::GetInstance(__animation);
2108
2109         IVisualElementAnimationStatusEventListener* pListener = pAnimationImpl->GetStatusEventListener();
2110
2111         if (pListener == null)
2112         {
2113                 return;
2114         }
2115
2116         if (completed == false)
2117         {
2118                 pListener->OnVisualElementAnimationFinished(__animation, __name, pAnimationImpl->GetEventTarget(), false);
2119                 return;
2120         }
2121
2122         switch (__status)
2123         {
2124         case _STATUS_START:
2125                 pListener->OnVisualElementAnimationStarted(__animation, __name, pAnimationImpl->GetEventTarget());
2126                 break;
2127
2128         case _STATUS_REPEAT:
2129                 pListener->OnVisualElementAnimationRepeated(__animation, __name, pAnimationImpl->GetEventTarget(), __currentRepeatCount);
2130                 break;
2131
2132         case _STATUS_STOP:
2133                 pListener->OnVisualElementAnimationFinished(__animation, __name, pAnimationImpl->GetEventTarget(), true);
2134                 break;
2135
2136         default:
2137                 break;
2138         }
2139 }
2140
2141
2142 }}}             // Tizen::Ui::Animations
2143