Merge "Layout fixes" into tizen
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / animation / animation-api.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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  */
17
18 // CLASS HEADER
19 #include "animation-api.h"
20 #include "path-wrapper.h"
21
22 // EXTERNAL INCLUDES
23 #include <cstring> // for strcmp
24 #include <dali/integration-api/debug.h>
25
26
27 // INTERNAL INCLUDES
28 #include <v8-utils.h>
29 #include <animation/animation-wrapper.h>
30 #include <object/property-value-wrapper.h>
31
32 namespace Dali
33 {
34
35 namespace V8Plugin
36 {
37
38 namespace // un named namespace
39 {
40
41 // @todo think about alternative ways of passing around
42 struct AlphaFuncStruct
43 {
44   const char* const name;
45   AlphaFunction alphaFunc;
46 };
47 /**
48  * Contains a list of alpha functions that can be used.
49  */
50 const AlphaFuncStruct AlphaFunctionTable[]=
51 {
52  {"default"               , AlphaFunctions::Default              },
53  {"linear"                , AlphaFunctions::Linear               },
54  {"square"                , AlphaFunctions::Square               },
55  {"reverse"               , AlphaFunctions::Reverse              },
56  {"easeIn"                , AlphaFunctions::EaseIn               },
57  {"easeOut"               , AlphaFunctions::EaseOut              },
58  {"easeInOut"             , AlphaFunctions::EaseInOut            },
59  {"easeInSine"            , AlphaFunctions::EaseInSine           },
60  {"easeOutSine"           , AlphaFunctions::EaseOutSine          },
61  {"easeInOutSine"         , AlphaFunctions::EaseInOutSine        },
62  {"easeInSine33"          , AlphaFunctions::EaseInSine33         },
63  {"easeOutSine33"         , AlphaFunctions::EaseOutSine33        },
64  {"easeInOutSine33"       , AlphaFunctions::EaseInOutSine33      },
65  {"easeInOutSine50"       , AlphaFunctions::EaseInOutSine50      },
66  {"easeInOutSine60"       , AlphaFunctions::EaseInOutSine60      },
67  {"easeInOutSine70"       , AlphaFunctions::EaseInOutSine70      },
68  {"easeInOutSine80"       , AlphaFunctions::EaseInOutSine80      },
69  {"easeInOutSine90"       , AlphaFunctions::EaseInOutSine90      },
70  {"doubleEaseInOutSine60" , AlphaFunctions::DoubleEaseInOutSine60},
71  {"easeOutQuint50"        , AlphaFunctions::EaseOutQuint50       },
72  {"easeOutQuint80"        , AlphaFunctions::EaseOutQuint80       },
73  {"bounce"                , AlphaFunctions::Bounce               },
74  {"bounceBack"            , AlphaFunctions::BounceBack           },
75  {"easeInBack"            , AlphaFunctions::EaseInBack           },
76  {"easeOutBack"           , AlphaFunctions::EaseOutBack          },
77  {"easeInOutBack"         , AlphaFunctions::EaseInOutBack        },
78  {"sin"                   , AlphaFunctions::Sin                  },
79  {"sin2x"                 , AlphaFunctions::Sin2x                }
80 };
81 const unsigned int AlphaFunctionTableCount = sizeof(AlphaFunctionTable)/sizeof(AlphaFunctionTable[0]);
82 const char* const DEFAULT_ALPHA_NAME = "default";
83 static AlphaFunction DEFAULT_ALPHA_FUNCTION = AlphaFunctions::Default;
84
85
86
87 AlphaFunction GetAlphaFunction( const std::string& alphaFuncName )
88 {
89   // This will normally get called just a few times during the application, so no point in doing anything clever
90   for( unsigned int i = 0; i < AlphaFunctionTableCount; i++)
91   {
92     const AlphaFuncStruct& alphaStruct( AlphaFunctionTable[i] );
93
94     if( std::strcmp( alphaStruct.name , alphaFuncName.c_str() ) == 0 )
95     {
96       return alphaStruct.alphaFunc;
97     }
98   }
99
100   DALI_LOG_ERROR("Failed to find alpha func |%s| \n", alphaFuncName.c_str() );
101   return AlphaFunctions::Default;
102 }
103
104 const char* const GetAlphaFunctionName(  AlphaFunction alphaFunc )
105 {
106   // This may get called 3 times during the application, so no point
107   // in doing anything clever
108
109   for( unsigned int i = 0; i < AlphaFunctionTableCount; i++)
110   {
111     const AlphaFuncStruct& alphaStruct( AlphaFunctionTable[i] );
112
113
114     if( alphaStruct.alphaFunc  == alphaFunc )
115     {
116       return alphaStruct.name;
117     }
118   }
119   return "default";
120 }
121
122
123 struct AnimationParameters
124 {
125   AnimationParameters( const Animation& anim)
126   : propertyIndex( Property::INVALID_INDEX  ),
127     alphaFunction( DEFAULT_ALPHA_FUNCTION),
128     delay( 0.f ),
129     duration(anim.GetDuration()),
130     optionsFound( false )
131   {
132   }
133
134   Handle target;
135   Property::Index propertyIndex;
136   Property::Value value;
137   KeyFrames keyFrames;
138   AlphaFunction alphaFunction;
139   float delay;
140   float duration;
141   bool optionsFound;
142 };
143
144 void GetAnimationOptions( v8::Isolate* isolate,
145                           v8::Local<v8::Value > options,
146                           AnimationParameters& animParams )
147 {
148   // animation options is an optional parameter passed in which holds
149   // optional settings
150   // var animOptions = {
151   //  alpha: "Bounce",
152   //  delay: 5,
153   //  duration: 20
154   // };
155   v8::HandleScope handleScope( isolate );
156
157   if( options->IsObject() )
158   {
159     v8::Local<v8::Object> obj = options->ToObject();
160     v8::Local<v8::Value> alphaValue = obj->Get( v8::String::NewFromUtf8( isolate, "alpha" ) );
161     if( alphaValue->IsString() )
162     {
163       animParams.optionsFound = true;
164       std::string alphaName = V8Utils::v8StringToStdString( alphaValue );
165       animParams.alphaFunction = GetAlphaFunction( alphaName );
166     }
167
168     v8::Local<v8::Value> delayValue = obj->Get( v8::String::NewFromUtf8( isolate, "delay" ) );
169     if( delayValue->IsNumber() )
170     {
171       animParams.optionsFound = true;
172       v8::Local<v8::Number> num = delayValue->ToNumber();
173       animParams.delay = num->Value();
174     }
175
176     v8::Local<v8::Value> durationValue = obj->Get( v8::String::NewFromUtf8( isolate, "duration" ) );
177     if( durationValue->IsNumber() )
178     {
179       animParams.optionsFound = true;
180       v8::Local<v8::Number> num = durationValue->ToNumber();
181       animParams.duration = num->Value();
182     }
183
184   }
185 }
186 KeyFrames GetKeyFrames( v8::Isolate* isolate, v8::Local<v8::Value > keyFrameArray )
187 {
188   // keyframe object is an array of
189   // {
190   //   float: progress
191   //   value: property value ( position/ rotation etc)
192   //   alpha: function
193   //
194   v8::HandleScope handleScope( isolate );
195
196   if( !keyFrameArray->IsObject() || !keyFrameArray->IsArray() )
197   {
198     DALI_SCRIPT_EXCEPTION( isolate, "missing keyframe array" );
199     return KeyFrames();
200   }
201
202   KeyFrames keyframes = KeyFrames::New();
203
204   v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast( keyFrameArray );
205   for( uint32_t i=0; i < array->Length() ; ++i)
206   {
207     v8::Handle<v8::Value> arrayItem =  array->Get( i );
208
209     if(!arrayItem->IsObject() )
210     {
211       DALI_SCRIPT_EXCEPTION( isolate, "missing keyframe object" );
212       return KeyFrames();
213     }
214     v8::Handle<v8::Object> keyFrameObject = arrayItem->ToObject();
215
216     // get keyframe.progress
217     v8::Handle<v8::Value> progress = keyFrameObject->Get(v8::String::NewFromUtf8( isolate, "progress"));
218     if( !progress->IsNumber() )
219     {
220       DALI_SCRIPT_EXCEPTION( isolate, "keyframe missing progress property" );
221       return keyframes;
222     }
223
224     // get keyframe.value
225     bool found(false);
226     v8::Handle<v8::Value> propertyValue = keyFrameObject->Get(v8::String::NewFromUtf8( isolate, "value"));
227     Property::Value value =  V8Utils::GetPropertyValueFromObject( found, isolate, propertyValue );
228     if( !found )
229     {
230       DALI_SCRIPT_EXCEPTION( isolate, "keyframe missing value property" );
231       return keyframes;
232     }
233
234     // get keyframe.alpha
235     v8::Handle<v8::Value> alphaValue = keyFrameObject->Get(v8::String::NewFromUtf8( isolate, "alpha"));
236     if( alphaValue->IsString() )
237     {
238       std::string alphaName = V8Utils::v8StringToStdString( alphaValue );
239       AlphaFunction alphaFunction = GetAlphaFunction( alphaName );
240       keyframes.Add( progress->NumberValue(), value, alphaFunction );
241     }
242     else
243     {
244       keyframes.Add( progress->NumberValue(), value );
245     }
246
247   }
248   return keyframes;
249
250 }
251 bool GetAnimationParameters(  v8::Isolate* isolate,
252                               const v8::FunctionCallbackInfo< v8::Value >& args,
253                               AnimationParameters& animParams,
254                               AnimationApi::AnimationParameterType type)
255 {
256   // used for things like anim.AnimateBy(  myImageActor, property-name,  property-value (or Javascript number array));
257   // 1 extract property handle from param1.
258   // 2 extract property name from param2  ( can be in the format "u-color" or "uColor"
259   // 3 extract PropertyValue from param3
260   // 4 extract animation options ( delay, duration, alpha func)
261
262   // 1 extract HANDLE
263   bool foundHandle;
264   animParams.target = V8Utils::GetHandleParameter( PARAMETER_0, foundHandle, isolate, args );
265   if( !foundHandle )
266   {
267     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 (Handle)" );
268     return false;
269   }
270
271   // 2 extract property name
272   bool foundPropName;
273   std::string propertyName = V8Utils::GetStringParameter( PARAMETER_1, foundPropName, isolate, args );
274   if( !foundPropName )
275   {
276     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 ( PropertyName )" );
277     return false;
278   }
279   // try both properties with dashes and without
280   Property::Index index = animParams.target.GetPropertyIndex( propertyName );
281
282   if( index == Property::INVALID_INDEX )
283   {
284     // convert the property name from "uColor" to "u-color"
285     std::string convetedName = V8Utils::JavaScriptNameToPropertyName( propertyName );
286     index = animParams.target.GetPropertyIndex( convetedName );
287   }
288
289   animParams.propertyIndex = index;
290
291   if( type == AnimationApi::PROPERTY_VALUE )
292   {
293     // 3 extract property value
294     bool foundPropValue( false );
295     animParams.value = V8Utils::GetPropertyValueParameter( PARAMETER_2, foundPropValue, isolate, args );
296     if( !foundPropValue )
297     {
298       DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 2 ( value )" );
299       return false;
300     }
301   }
302   else  // type == KEYFRAMES
303   {
304     animParams.keyFrames = GetKeyFrames(isolate, args[2]);
305   }
306   // 4 extract animation options
307   GetAnimationOptions( isolate, args[3], animParams );
308
309   return true;
310 }
311
312 Animation GetAnimation( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
313 {
314   v8::HandleScope handleScope( isolate );
315
316   v8::Local<v8::Object> object = args.This();
317   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField( 0 ) );
318   void* ptr = field->Value();
319
320   AnimationWrapper* wrapper = static_cast<AnimationWrapper *>( ptr );
321   return wrapper->GetAnimation();
322 }
323
324
325 } // un-named namespace
326
327 /**
328  * Constructor
329  *
330  * @constructor
331  * @for Animation
332  * @method Animation
333  * @param {float} duration
334  *
335  */
336 Animation AnimationApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
337 {
338   v8::Isolate* isolate = args.GetIsolate();
339   v8::HandleScope handleScope( isolate );
340
341   bool found( false );
342   float value = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 1.f /* default */);
343   if( !found )
344   {
345     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
346     return Animation();
347   }
348   // get the duration
349   return Animation::New( value );
350 }
351
352 /**
353  * Set the animation duration.
354  * @method setDuration
355  * @for Animation
356  * @param {float} duration in seconds
357  *
358  */
359 void AnimationApi::SetDuration( const v8::FunctionCallbackInfo< v8::Value >& args )
360 {
361   v8::Isolate* isolate = args.GetIsolate();
362   v8::HandleScope handleScope( isolate );
363
364   Animation anim = GetAnimation( isolate, args );
365
366   bool found( false );
367   float value = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 1.f /* default */);
368   if( !found )
369   {
370     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
371     return;
372   }
373   anim.SetDuration( value );
374 }
375 /**
376  * Get the animation duration.
377  * @method getDuration
378  * @for Animation
379  * @return {float} duration in seconds
380  *
381  */
382 void AnimationApi::GetDuration( const v8::FunctionCallbackInfo< v8::Value >& args )
383 {
384   v8::Isolate* isolate = args.GetIsolate();
385   v8::HandleScope handleScope( isolate );
386
387   Animation anim = GetAnimation( isolate, args );
388
389   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetDuration() ) );
390
391 }
392 /**
393  * Set whether the animation will loop.
394  * @method setLooping
395  * @for Animation
396  * @param {bool} looping enabled
397  *
398  */
399 void AnimationApi::SetLooping( const v8::FunctionCallbackInfo< v8::Value >& args )
400 {
401   v8::Isolate* isolate = args.GetIsolate();
402   v8::HandleScope handleScope( isolate );
403
404   Animation anim = GetAnimation( isolate, args );
405
406   bool found( false );
407   bool value = V8Utils::GetBooleanParameter( PARAMETER_0, found, isolate, args );
408   if( !found )
409   {
410     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
411   }
412   else
413   {
414     anim.SetLooping( value );
415   }
416
417 }
418 /**
419  * Query whether the animation will loop.
420  * @method isLooping
421  * @for Animation
422  * @return {bool} looping enabled
423  *
424  */
425 void AnimationApi::IsLooping( const v8::FunctionCallbackInfo< v8::Value >& args )
426 {
427   v8::Isolate* isolate = args.GetIsolate();
428   v8::HandleScope handleScope( isolate );
429
430   Animation anim = GetAnimation( isolate, args );
431
432   args.GetReturnValue().Set( v8::Boolean::New( isolate, anim.IsLooping() ) );
433 }
434
435 /**
436  * Set the end action of the animation.
437  *
438  * This action is performed when the animation ends.
439  * Default end action is bake
440  * @method setEndAction
441  * @for Animation
442  * @param {integer} bake mode
443  * @example
444  *       anim.setEndAction( dali.ANIMATION_BAKE ); // When the animation ends, the animated property values are saved.
445  *       anim.setEndAction( dali.ANIMATION_DISCARD ); //  When the animation ends, the animated property values are forgotten.
446  *       anim.setEndAction( dali.ANIMATION_BAKE_FINAL ); // If the animation is stopped, the animated property values are saved as if the animation had run to completion, otherwise behaves like Bake.
447  */
448 void AnimationApi::SetEndAction( const v8::FunctionCallbackInfo< v8::Value >& args )
449 {
450   v8::Isolate* isolate = args.GetIsolate();
451   v8::HandleScope handleScope( isolate );
452
453   Animation anim = GetAnimation( isolate, args );
454
455   bool found( false );
456   int value = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
457   if( !found )
458   {
459     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
460   }
461   else
462   {
463     anim.SetEndAction( static_cast<Animation::EndAction>( value ) );
464   }
465 }
466
467 /**
468  * Returns the end action of the animation.
469
470  * @method getEndAction
471  * @for Animation
472  * @return {integer} bake mode
473  *
474  * There are 3 different bake modes
475  * @example
476  *     dali.ANIMATION_BAKE  // When the animation ends, the animated property values are saved.
477  *     dali.ANIMATION_DISCARD // When the animation ends, the animated property values are forgotten.
478  *     dali.ANIMATION_BAKE_FINAL  // If the animation is stopped, the animated property values are saved as if the animation had run to completion, otherwise behaves like Bake.
479  */
480 void AnimationApi::GetEndAction( const v8::FunctionCallbackInfo< v8::Value >& args )
481 {
482   v8::Isolate* isolate = args.GetIsolate();
483   v8::HandleScope handleScope( isolate );
484
485   Animation anim = GetAnimation( isolate, args );
486
487   args.GetReturnValue().Set( v8::Integer::New( isolate, anim.GetEndAction() ) );
488 }
489
490 /**
491  * Set the disconnect action of the animation.
492  * If any of the animated property owners are disconnected from the stage, this action is performed.
493  * Default disconnection action is BakeFinal.
494  * @method setDisconnectAction
495  * @for Animation
496  * @param {integer} end mode
497  *
498  * There are 3 different end modes
499  * @example
500  *     dali.ANIMATION_BAKE  // When the animation is destroyed, the animated property values are saved.
501  *     dali.ANIMATION_DISCARD // When the animation is destroyed, the animated property values are forgotten.
502  *     dali.ANIMATION_BAKE_FINAL  // When the animation is destroyed, the animated property values are saved as if the animation had run to completion, otherwise behaves like Bake.
503  */
504 void AnimationApi::SetDisconnectAction( const v8::FunctionCallbackInfo< v8::Value >& args )
505 {
506   v8::Isolate* isolate = args.GetIsolate();
507   v8::HandleScope handleScope( isolate );
508
509   Animation anim = GetAnimation( isolate, args );
510
511   bool found( false );
512   int value = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
513   if( !found )
514   {
515     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
516   }
517   else
518   {
519     anim.SetDisconnectAction( static_cast<Animation::EndAction>( value ) );
520   }
521 }
522
523 /**
524  * Returns the disconnect action of the animation.
525  * @method getDisconnectAction
526  * @for Animation
527  * @return {integer} end mode
528  */
529 void AnimationApi::GetDisconnectAction( const v8::FunctionCallbackInfo< v8::Value >& args )
530 {
531   v8::Isolate* isolate = args.GetIsolate();
532   v8::HandleScope handleScope( isolate );
533
534   Animation anim = GetAnimation( isolate, args );
535
536   args.GetReturnValue().Set( v8::Integer::New( isolate, anim.GetDisconnectAction() ) );
537 }
538 /**
539  * Set the default alpha function for an animation.
540  * @method setDefaultAlphaFunction
541  * @for Animation
542  * @param {string} alpha function
543  */
544 void AnimationApi::SetDefaultAlphaFunction( const v8::FunctionCallbackInfo< v8::Value >& args )
545 {
546   v8::Isolate* isolate = args.GetIsolate();
547   v8::HandleScope handleScope( isolate );
548
549   Animation anim = GetAnimation( isolate, args );
550
551   bool found( false );
552   std::string alphaFunc = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
553   if( !found )
554   {
555     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
556   }
557   else
558   {
559     AlphaFunction func = GetAlphaFunction( alphaFunc );
560     anim.SetDefaultAlphaFunction( func );
561   }
562
563 }
564 /**
565  * Get the default alpha function for an animation.
566  * @method getDefaultAlphaFunction
567  * @for Animation
568  * @return {string} alpha function
569  */
570 void AnimationApi::GetDefaultAlphaFunction( const v8::FunctionCallbackInfo<v8::Value>& args )
571 {
572   v8::Isolate* isolate = args.GetIsolate();
573   v8::HandleScope handleScope( isolate );
574
575   Animation anim = GetAnimation( isolate, args );
576
577   std::string alphaName = GetAlphaFunctionName(  anim.GetDefaultAlphaFunction() );
578
579
580   args.GetReturnValue().Set( v8::String::NewFromUtf8( isolate, alphaName.c_str() ) );
581 }
582
583 /**
584  * Get the current progress of the animation.
585  * @method getCurrentProgress
586  * @for Animation
587  * @return {float} The current progress as a normalized value between [0..1].
588  *
589  */
590 void AnimationApi::GetCurrentProgress( const v8::FunctionCallbackInfo< v8::Value >& args )
591 {
592   v8::Isolate* isolate = args.GetIsolate();
593   v8::HandleScope handleScope( isolate );
594
595   Animation anim = GetAnimation( isolate, args );
596
597   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetCurrentProgress() ) );
598 }
599
600 /**
601  * Specifies an speed factor for the animation.
602  *
603  * The speed factor is a multiplier of the normal velocity of the animation. Values between [0,1] will
604  * slow down the animation and values above one will speed up the animation. It is also possible to specify a negative multiplier
605  * to play the animation in reverse.
606  *
607  * @method setSpeedFactor
608  * @for Animation
609  * @param {float}  value which will multiply the velocity.
610  * @example
611  *     anim.setSpeedFactor(2);
612  *     anim.play();             // plays the animation twice as fast
613  *
614  *
615  *     anim.setSpeedFactor(0.5);
616  *     anim.play();             // plays the animation half speed
617  *
618  */
619 void AnimationApi::SetSpeedFactor( const v8::FunctionCallbackInfo< v8::Value >& args )
620 {
621   v8::Isolate* isolate = args.GetIsolate();
622   v8::HandleScope handleScope( isolate );
623
624   Animation anim = GetAnimation( isolate, args );
625
626   bool found( false );
627   float speedFactor = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
628   if( !found )
629   {
630     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
631   }
632   else
633   {
634     anim.SetSpeedFactor( speedFactor );
635   }
636
637 }
638
639 /**
640  * Retrieve the speed factor of the animation
641  *
642  *
643  * @method getSpeedFactor
644  * @for Animation
645  * @return {float} speed factor
646  */
647 void AnimationApi::GetSpeedFactor( const v8::FunctionCallbackInfo< v8::Value >& args )
648 {
649   v8::Isolate* isolate = args.GetIsolate();
650   v8::HandleScope handleScope( isolate );
651
652   Animation anim = GetAnimation( isolate, args );
653
654   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetSpeedFactor() ) );
655 }
656
657 /**
658  * Set the playing range.
659  * Animation will play between the values specified.
660  * Both values ( range.x and range.y ) should be between 0-1,
661  * otherwise they will be ignored.
662  * If the range provided is not in proper order ( minimum,maximum), it will be reordered.
663  * @method setPlayRange
664  * @for Animation
665  * @param {Object} Range
666  * @param {Float} Range.start
667  * @param {Float} Range.end
668  * @example
669  *     var range = {  start:0.1, end:0.6 };
670  *     anim.setPlayRange( range );
671  */
672 void AnimationApi::SetPlayRange( const v8::FunctionCallbackInfo< v8::Value >& args )
673 {
674   v8::Isolate* isolate = args.GetIsolate();
675   v8::HandleScope handleScope( isolate );
676
677   Animation anim = GetAnimation( isolate, args );
678   Vector2 range(0,0);
679
680   if( args.Length() != 1 )
681   {
682     DALI_SCRIPT_EXCEPTION( isolate, "missing / invalid parameters" );
683     return;
684   }
685   v8::Local<v8::Value > rangeValue = args[0];
686   if( !rangeValue->IsObject() )
687   {
688     DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters" );
689     return;
690   }
691   v8::Local<v8::Object> obj = rangeValue->ToObject();
692   v8::Local<v8::Value> startValue = obj->Get( v8::String::NewFromUtf8( isolate, "start" ) );
693   v8::Local<v8::Value> endValue = obj->Get( v8::String::NewFromUtf8( isolate, "end" ) );
694
695   if( startValue->IsNumber() &&  endValue->IsNumber())
696   {
697         range.x= startValue->ToNumber()->Value();
698         range.y = endValue->ToNumber()->Value();
699   }
700   else
701   {
702     DALI_SCRIPT_EXCEPTION( isolate, "missing start/end value" );
703     return;
704   }
705
706   anim.SetPlayRange( range );
707
708 }
709
710 /**
711  * Get the playing range.
712  * @method getPlayRange
713  * @for Animation
714  * @return {Object} Range with { start: ,  end: } properties.
715  */
716 void AnimationApi::GetPlayRange( const v8::FunctionCallbackInfo< v8::Value >& args )
717 {
718   v8::Isolate* isolate = args.GetIsolate();
719   v8::EscapableHandleScope handleScope( isolate );
720   Animation anim = GetAnimation( isolate, args );
721
722
723   v8::Local<v8::Object> rangeObject = v8::Object::New( isolate );
724
725   Vector2 range = anim.GetPlayRange();
726
727  // set device id
728   rangeObject->Set( v8::String::NewFromUtf8( isolate, "start"), v8::Number::New( isolate,range.x ));
729
730    // set state
731   rangeObject->Set( v8::String::NewFromUtf8( isolate, "end"), v8::Number::New( isolate,range.y ));
732
733   args.GetReturnValue().Set( rangeObject );
734 }
735
736
737 /**
738  * Sets the progress of the animation.
739  * The animation will play (or continue playing) from this point. The progress
740  * must be in the 0-1 interval or in the play range interval if defined ( See SetPlayRange ),
741  * otherwise, it will be ignored.
742  *
743  * @method setCurrentProgress
744  * @for Animation
745  * @param {float}  progress The new progress as a normalized value between [0,1] or between the
746  * play range if specified.
747  */
748 void AnimationApi::SetCurrentProgress( const v8::FunctionCallbackInfo< v8::Value >& args )
749 {
750   v8::Isolate* isolate = args.GetIsolate();
751   v8::HandleScope handleScope( isolate );
752
753   Animation anim = GetAnimation( isolate, args );
754
755   bool found( false );
756
757   float progress = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
758   if( !found )
759   {
760     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
761     return;
762   }
763   anim.SetCurrentProgress( progress );
764
765 }
766
767 /**
768  *
769  *  Play the animation from a given point.
770  * The progress must be in the 0-1 interval or in the play range interval if defined ( See SetPlayRange ),
771  * otherwise, it will be ignored.
772  * @method playFrom
773  * @for Animation
774  * @param {float} progress A value between [0,1], or between the play range if specified, form where the animation should start playing
775  */
776 void AnimationApi::PlayFrom( const v8::FunctionCallbackInfo< v8::Value >& args )
777 {
778   v8::Isolate* isolate = args.GetIsolate();
779   v8::HandleScope handleScope( isolate );
780
781   Animation anim = GetAnimation( isolate, args );
782
783   bool found( false );
784
785   float progress = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
786   if( !found )
787   {
788     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
789     return;
790   }
791   anim.PlayFrom( progress );
792
793 }
794
795 /**
796  * Play the animation
797  * @method play
798  * @for Animation
799  */
800 void AnimationApi::Play( const v8::FunctionCallbackInfo<v8::Value>& args )
801 {
802   v8::Isolate* isolate = args.GetIsolate();
803   v8::HandleScope handleScope( isolate );
804
805   Animation anim = GetAnimation( isolate, args );
806   anim.Play();
807 }
808 /**
809  * Pause the animation
810  * @method pause
811  * @for Animation
812  */
813 void AnimationApi::Pause( const v8::FunctionCallbackInfo<v8::Value>& args )
814 {
815   v8::Isolate* isolate = args.GetIsolate();
816   v8::HandleScope handleScope( isolate );
817
818   Animation anim = GetAnimation( isolate, args );
819   anim.Pause();
820 }
821 /**
822  * Stop the animation
823  * @method stop
824  * @for Animation
825  */
826 void AnimationApi::Stop( const v8::FunctionCallbackInfo<v8::Value>& args )
827 {
828   v8::Isolate* isolate = args.GetIsolate();
829   v8::HandleScope handleScope( isolate );
830
831   Animation anim = GetAnimation( isolate, args );
832   anim.Stop();
833 }
834 /**
835  * Clear the animation
836  * This disconnects any objects that were being animated, effectively stopping the animation.
837  * @method clear
838  * @for Animation
839  */
840 void AnimationApi::Clear( const v8::FunctionCallbackInfo<v8::Value>& args )
841 {
842   v8::Isolate* isolate = args.GetIsolate();
843   v8::HandleScope handleScope( isolate );
844
845   Animation anim = GetAnimation( isolate, args );
846   anim.Clear();
847 }
848
849
850 void AnimationApi::Animate( const v8::FunctionCallbackInfo<v8::Value>& args )
851 {
852   v8::Isolate* isolate = args.GetIsolate();
853   v8::HandleScope handleScope( isolate );
854
855   Animation anim = GetAnimation( isolate, args );
856   AnimationParameters animParams( anim );
857   bool found(false);
858
859   //Get actor
860   Dali::Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
861   if( !found )
862   {
863     DALI_SCRIPT_EXCEPTION( isolate, "Missing actor parameter");
864     return;
865   }
866
867   //Get path
868   Dali::Path path;
869   BaseWrappedObject* wrapper = V8Utils::GetWrappedDaliObjectParameter( PARAMETER_1, BaseWrappedObject::PATH, isolate, args);
870   PathWrapper* pathWrapper = static_cast< PathWrapper*>( wrapper );
871   if( !pathWrapper )
872   {
873     return;
874   }
875   path = pathWrapper->GetPath();
876
877   //Get forward vector
878   bool bFound(false);
879   Vector3 forward = V8Utils::GetVector3Parameter( PARAMETER_2, bFound, isolate, args );
880   if( !bFound )
881   {
882     return;
883   }
884
885   //Get animation options
886   GetAnimationOptions( isolate, args[3], animParams );
887   if( animParams.optionsFound )
888   {
889     anim.Animate( actor, path, forward, animParams.alphaFunction, TimePeriod( animParams.delay, animParams.duration) );
890   }
891   else
892   {
893     anim.Animate( actor, path, forward );
894   }
895 }
896
897 /**
898  *
899  * Animate a property value by a relative amount.
900  *
901  * The effect will start & end when the animation begins & ends.
902  * @method animateBy
903  * @for Animation
904  * @param {Object} target object that contains a property to be animated (e.g. myActor )
905  * @param {String} property name (e.g. "position" )
906  * @param {Object} relativeValue The property value will change by this amount.
907  * @param {Object} [options] Animation options.
908  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
909  * @param {Float} [options.duration] duration of the animation
910  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
911  *
912  * @example
913  *
914  *     // animation x position
915  *     var anim = new dali.Animation( 1 );
916  *     anim.animateBy( imageActor,"positionX", 30 );
917  *     anim.play();
918  *
919  *     // animate x,y,z position with the optional animation options
920  *     var options = {
921  *        delay: 3,     // 3 second delay before starting
922  *        duration: 5,  // 5 second duration
923  *        alpha:"easeInOutSine"   // Speeds up and slows to a gradual stop
924  *     }
925  *
926  *     anim.animateBy( imageActor,"position", [100,200,0], options );
927  *
928  */
929 void AnimationApi::AnimateBy( const v8::FunctionCallbackInfo<v8::Value>& args )
930 {
931   v8::Isolate* isolate = args.GetIsolate();
932   v8::HandleScope handleScope( isolate );
933
934   Animation anim = GetAnimation( isolate, args );
935   AnimationParameters animParams( anim );
936
937   // grab all the parameters
938   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::PROPERTY_VALUE);
939   if( !ok )
940   {
941     // GetAnimationParameters will log
942     return;
943   }
944
945   if( animParams.optionsFound )
946   {
947     anim.AnimateBy( Property( animParams.target, animParams.propertyIndex ),
948                               animParams.value,
949                               animParams.alphaFunction,
950                               TimePeriod( animParams.delay, animParams.duration) );
951   }
952   else
953   {
954     anim.AnimateBy( Property( animParams.target, animParams.propertyIndex ), animParams.value );
955   }
956
957 }
958
959 /**
960  *
961  * Animate a property to a destination value.
962  *
963  * The effect will start & end when the animation begins & ends.
964  * @method animateTo
965  * @for Animation
966  * @param {Object} target object that contains a property to be animated (e.g. myActor )
967  * @param {String} property name (e.g. "position" )
968  * @param {Object} destinationValue The property value will changed to this value
969  * @param {Object} [options] Animation options.
970  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
971  * @param {Float} [options.duration] duration of the animation
972  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
973  *
974  * @example
975  *
976  *     var anim = new dali.Animation( 1 );
977  *     anim.animateTo( imageActor,"positionX", 30 );
978  *     anim.play();
979  *
980  *
981  *     // with the optional animation options object
982  *     var options = {
983  *        delay: 3,     // 3 second delay before starting
984  *        duration: 5,  // 5 second duration
985  *        alpha:"easeInOutSine"   // Speeds up and slows to a gradual stop
986  *     }
987  *
988  *     anim.animateTo( imageActor,"position", [100,200,0], options );
989  *
990  */
991 void AnimationApi::AnimateTo( const v8::FunctionCallbackInfo< v8::Value >& args )
992 {
993   v8::Isolate* isolate = args.GetIsolate();
994   v8::HandleScope handleScope( isolate );
995
996   Animation anim = GetAnimation( isolate, args );
997   AnimationParameters animParams( anim );
998
999   // grab all the parameters
1000   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::PROPERTY_VALUE );
1001   if( !ok )
1002   {
1003     // GetAnimationParameters will log
1004     return;
1005   }
1006
1007   if( animParams.optionsFound )
1008   {
1009
1010     anim.AnimateTo( Property( animParams.target,animParams.propertyIndex ),
1011                                   animParams.value,
1012                                   animParams.alphaFunction,
1013                                   TimePeriod( animParams.delay, animParams.duration) );
1014   }
1015   else
1016   {
1017     anim.AnimateTo( Property( animParams.target, animParams.propertyIndex ), animParams.value );
1018   }
1019 }
1020
1021 /**
1022  *
1023  * Animate a property between keyframes.
1024  *
1025  * The effect will start & end when the animation begins & ends.
1026  * @method animateBetween
1027  * @for Animation
1028  * @param {Object} target object that contains a property to be animated (e.g. myActor )
1029  * @param {String} property name (e.g. "position" )
1030  * @param {Object} keyframes array of keyframe objects
1031  * @param {Object} [options] Animation options.
1032  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
1033  * @param {Float} [options.duration] duration of the animation
1034  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
1035  *
1036  *
1037  * @example
1038  *
1039  *  create some keyframes to move an actor around a square, and return to the start
1040  * </br >
1041  *  <img src="../assets/img/keyframe-animation.png">
1042  *
1043  *
1044  *     var keyframes = [
1045  *     {
1046  *       progress:0.0,
1047  *       value: [0,0,0]
1048  *     },
1049  *     {
1050  *       progress:0.25,
1051  *       value: [500,0,0]
1052  *     },
1053  *
1054  *     {
1055  *       progress:0.5,
1056  *       value: [500,500,0]
1057  *     },
1058  *     {
1059  *       progress:0.75,
1060  *       value: [0,500,0]
1061  *     },
1062  *     {
1063  *       progress:1.0,
1064  *       value: [0,0,0]
1065  *     } ];
1066  *
1067  *
1068  *     anim.animateBetween( imageActor,"position", keyframes );
1069  *
1070  */
1071 void AnimationApi::AnimateBetween( const v8::FunctionCallbackInfo< v8::Value >& args )
1072 {
1073   v8::Isolate* isolate = args.GetIsolate();
1074   v8::HandleScope handleScope( isolate );
1075
1076   Animation anim = GetAnimation( isolate, args );
1077   AnimationParameters animParams( anim );
1078
1079   // grab all the parameters
1080   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::KEYFRAMES );
1081   if( !ok )
1082   {
1083     // GetAnimationParameters will log
1084     return;
1085   }
1086
1087   // if animation options exist...
1088   if( animParams.optionsFound )
1089   {
1090
1091     anim.AnimateBetween( Property( animParams.target,animParams.propertyIndex ),
1092                                   animParams.keyFrames,
1093                                   animParams.alphaFunction,
1094                                   TimePeriod( animParams.delay, animParams.duration) );
1095   }
1096   else
1097   {
1098     anim.AnimateBetween( Property( animParams.target, animParams.propertyIndex ), animParams.keyFrames );
1099   }
1100 }
1101
1102 /**
1103  * show an actor during the animation.
1104  *
1105  * This is a helper, which simulates animating the visibility property of an actor
1106  * with zero duration ( it is just a boolean).
1107  * e.g. it performs  anim.AnimateTo( actor,"visible",true, { delay:delay: duration:0 } );
1108  * @method show
1109  * @for Animation
1110  * @param {Object} Actor
1111  * @param {float} delay until the actor is shown
1112  */
1113 void AnimationApi::Show( const v8::FunctionCallbackInfo< v8::Value >& args )
1114 {
1115   v8::Isolate* isolate = args.GetIsolate();
1116   v8::HandleScope handleScope( isolate );
1117   Animation anim = GetAnimation( isolate, args );
1118   bool found( false );
1119
1120   Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
1121   if( !found)
1122   {
1123     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 actor" );
1124     return;
1125   }
1126   // get the duration
1127   float delay = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 1.f /* default */);
1128   if( !found )
1129   {
1130     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 delay" );
1131     return;
1132   }
1133   anim.Show( actor, delay );
1134
1135 }
1136
1137 /**
1138  * hide an actor during the animation.
1139  *
1140  * This is a helper, which simulates animating the visibility property of an actor
1141  * with zero duration ( it is just a boolean).
1142  * e.g. it performs  anim.AnimateTo( actor,"visible",false, { delay:delay: duration:0 } );
1143  * @method hide
1144  * @for Animation
1145  * @param {Object} Actor
1146  * @param {float} delay until the actor is hidden
1147  */
1148 void AnimationApi::Hide( const v8::FunctionCallbackInfo< v8::Value >& args )
1149 {
1150   v8::Isolate* isolate = args.GetIsolate();
1151   v8::HandleScope handleScope( isolate );
1152   Animation anim = GetAnimation( isolate, args );
1153   bool found( false );
1154   Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
1155   if( !found )
1156   {
1157     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 actor" );
1158     return;
1159   }
1160
1161   // get the duration
1162   float delay = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 1.f /* default */);
1163   if( !found )
1164   {
1165     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 delay" );
1166     return;
1167   }
1168   anim.Hide( actor, delay );
1169 }
1170
1171
1172
1173
1174 } // namespace V8Plugin
1175
1176 } // namespace Dali