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