Add more shared C++/JavaScript docs and add JavaScript wrapping guide
[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  ( can be in the format "u-color" or "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     // convert the property name from "uColor" to "u-color"
277     std::string convetedName = V8Utils::JavaScriptNameToPropertyName( propertyName );
278     index = animParams.target.GetPropertyIndex( convetedName );
279   }
280
281   animParams.propertyIndex = index;
282
283   if( type == AnimationApi::PROPERTY_VALUE )
284   {
285     // 3 extract property value
286     bool foundPropValue( false );
287     animParams.value = V8Utils::GetPropertyValueParameter( PARAMETER_2, foundPropValue, isolate, args );
288     if( !foundPropValue )
289     {
290       DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 2 ( value )" );
291       return false;
292     }
293   }
294   else  // type == KEYFRAMES
295   {
296     animParams.keyFrames = GetKeyFrames(isolate, args[2]);
297   }
298   // 4 extract animation options
299   GetAnimationOptions( isolate, args[3], animParams );
300
301   return true;
302 }
303
304 Animation GetAnimation( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
305 {
306   v8::HandleScope handleScope( isolate );
307
308   v8::Local<v8::Object> object = args.This();
309   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField( 0 ) );
310   void* ptr = field->Value();
311
312   AnimationWrapper* wrapper = static_cast<AnimationWrapper *>( ptr );
313   return wrapper->GetAnimation();
314 }
315
316
317 } // un-named namespace
318
319 /**
320  * Constructor
321  *
322  * @constructor
323  * @for Animation
324  * @method Animation
325  * @param {float} duration
326  *
327  */
328 Animation AnimationApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
329 {
330   v8::Isolate* isolate = args.GetIsolate();
331   v8::HandleScope handleScope( isolate );
332
333   bool found( false );
334   float value = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 1.f /* default */);
335   if( !found )
336   {
337     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
338     return Animation();
339   }
340   // get the duration
341   return Animation::New( value );
342 }
343
344 /**
345  * Set the animation duration.
346  * @method setDuration
347  * @for Animation
348  * @param {float} duration in seconds
349  *
350  */
351 void AnimationApi::SetDuration( const v8::FunctionCallbackInfo< v8::Value >& args )
352 {
353   v8::Isolate* isolate = args.GetIsolate();
354   v8::HandleScope handleScope( isolate );
355
356   Animation anim = GetAnimation( isolate, args );
357
358   bool found( false );
359   float value = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 1.f /* default */);
360   if( !found )
361   {
362     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
363     return;
364   }
365   anim.SetDuration( value );
366 }
367 /**
368  * Get the animation duration.
369  * @method getDuration
370  * @for Animation
371  * @return {float} duration in seconds
372  *
373  */
374 void AnimationApi::GetDuration( const v8::FunctionCallbackInfo< v8::Value >& args )
375 {
376   v8::Isolate* isolate = args.GetIsolate();
377   v8::HandleScope handleScope( isolate );
378
379   Animation anim = GetAnimation( isolate, args );
380
381   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetDuration() ) );
382
383 }
384 /**
385  * Set whether the animation will loop.
386  * @method setLooping
387  * @for Animation
388  * @param {bool} looping enabled
389  *
390  */
391 void AnimationApi::SetLooping( const v8::FunctionCallbackInfo< v8::Value >& args )
392 {
393   v8::Isolate* isolate = args.GetIsolate();
394   v8::HandleScope handleScope( isolate );
395
396   Animation anim = GetAnimation( isolate, args );
397
398   bool found( false );
399   bool value = V8Utils::GetBooleanParameter( PARAMETER_0, found, isolate, args );
400   if( !found )
401   {
402     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
403   }
404   else
405   {
406     anim.SetLooping( value );
407   }
408
409 }
410 /**
411  * Query whether the animation will loop.
412  * @method isLooping
413  * @for Animation
414  * @return {bool} looping enabled
415  *
416  */
417 void AnimationApi::IsLooping( const v8::FunctionCallbackInfo< v8::Value >& args )
418 {
419   v8::Isolate* isolate = args.GetIsolate();
420   v8::HandleScope handleScope( isolate );
421
422   Animation anim = GetAnimation( isolate, args );
423
424   args.GetReturnValue().Set( v8::Boolean::New( isolate, anim.IsLooping() ) );
425 }
426
427 /**
428  * Set the end action of the animation.
429  *
430  * This action is performed when the animation ends.
431  * Default end action is bake
432  * @method setEndAction
433  * @for Animation
434  * @param {integer} bake mode
435  * @example
436  *       anim.setEndAction( dali.ANIMATION_BAKE ); // When the animation ends, the animated property values are saved.
437  *       anim.setEndAction( dali.ANIMATION_DISCARD ); //  When the animation ends, the animated property values are forgotten.
438  *       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.
439  */
440 void AnimationApi::SetEndAction( const v8::FunctionCallbackInfo< v8::Value >& args )
441 {
442   v8::Isolate* isolate = args.GetIsolate();
443   v8::HandleScope handleScope( isolate );
444
445   Animation anim = GetAnimation( isolate, args );
446
447   bool found( false );
448   int value = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
449   if( !found )
450   {
451     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
452   }
453   else
454   {
455     anim.SetEndAction( static_cast<Animation::EndAction>( value ) );
456   }
457 }
458
459 /**
460  * Returns the end action of the animation.
461
462  * @method getEndAction
463  * @for Animation
464  * @return {integer} bake mode
465  *
466  * There are 3 different bake modes
467  * @example
468  *     dali.ANIMATION_BAKE  // When the animation ends, the animated property values are saved.
469  *     dali.ANIMATION_DISCARD // When the animation ends, the animated property values are forgotten.
470  *     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.
471  */
472 void AnimationApi::GetEndAction( const v8::FunctionCallbackInfo< v8::Value >& args )
473 {
474   v8::Isolate* isolate = args.GetIsolate();
475   v8::HandleScope handleScope( isolate );
476
477   Animation anim = GetAnimation( isolate, args );
478
479   args.GetReturnValue().Set( v8::Integer::New( isolate, anim.GetEndAction() ) );
480 }
481
482 /**
483  * Set the disconnect action of the animation.
484  * If any of the animated property owners are disconnected from the stage, this action is performed.
485  * Default disconnection action is BakeFinal.
486  * @method setDisconnectAction
487  * @for Animation
488  * @param {integer} end mode
489  *
490  * There are 3 different end modes
491  * @example
492  *     dali.ANIMATION_BAKE  // When the animation is destroyed, the animated property values are saved.
493  *     dali.ANIMATION_DISCARD // When the animation is destroyed, the animated property values are forgotten.
494  *     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.
495  */
496 void AnimationApi::SetDisconnectAction( const v8::FunctionCallbackInfo< v8::Value >& args )
497 {
498   v8::Isolate* isolate = args.GetIsolate();
499   v8::HandleScope handleScope( isolate );
500
501   Animation anim = GetAnimation( isolate, args );
502
503   bool found( false );
504   int value = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
505   if( !found )
506   {
507     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
508   }
509   else
510   {
511     anim.SetDisconnectAction( static_cast<Animation::EndAction>( value ) );
512   }
513 }
514
515 /**
516  * Returns the disconnect action of the animation.
517  * @method getDisconnectAction
518  * @for Animation
519  * @return {integer} end mode
520  */
521 void AnimationApi::GetDisconnectAction( const v8::FunctionCallbackInfo< v8::Value >& args )
522 {
523   v8::Isolate* isolate = args.GetIsolate();
524   v8::HandleScope handleScope( isolate );
525
526   Animation anim = GetAnimation( isolate, args );
527
528   args.GetReturnValue().Set( v8::Integer::New( isolate, anim.GetDisconnectAction() ) );
529 }
530 /**
531  * Set the default alpha function for an animation.
532  * @method setDefaultAlphaFunction
533  * @for Animation
534  * @param {string} alpha function
535  */
536 void AnimationApi::SetDefaultAlphaFunction( const v8::FunctionCallbackInfo< v8::Value >& args )
537 {
538   v8::Isolate* isolate = args.GetIsolate();
539   v8::HandleScope handleScope( isolate );
540
541   Animation anim = GetAnimation( isolate, args );
542
543   bool found( false );
544   std::string alphaFunc = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
545   if( !found )
546   {
547     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
548   }
549   else
550   {
551     AlphaFunction func = GetAlphaFunction( alphaFunc );
552     anim.SetDefaultAlphaFunction( func );
553   }
554
555 }
556 /**
557  * Get the default alpha function for an animation.
558  * @method getDefaultAlphaFunction
559  * @for Animation
560  * @return {string} alpha function
561  */
562 void AnimationApi::GetDefaultAlphaFunction( const v8::FunctionCallbackInfo<v8::Value>& args )
563 {
564   v8::Isolate* isolate = args.GetIsolate();
565   v8::HandleScope handleScope( isolate );
566
567   Animation anim = GetAnimation( isolate, args );
568
569   std::string alphaName = GetAlphaFunctionName(  anim.GetDefaultAlphaFunction() );
570
571
572   args.GetReturnValue().Set( v8::String::NewFromUtf8( isolate, alphaName.c_str() ) );
573 }
574
575 /**
576  * Get the current progress of the animation.
577  * @method getCurrentProgress
578  * @for Animation
579  * @return {float} The current progress as a normalized value between [0..1].
580  *
581  */
582 void AnimationApi::GetCurrentProgress( const v8::FunctionCallbackInfo< v8::Value >& args )
583 {
584   v8::Isolate* isolate = args.GetIsolate();
585   v8::HandleScope handleScope( isolate );
586
587   Animation anim = GetAnimation( isolate, args );
588
589   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetCurrentProgress() ) );
590 }
591
592 /**
593  * Specifies an speed factor for the animation.
594  *
595  * The speed factor is a multiplier of the normal velocity of the animation. Values between [0,1] will
596  * slow down the animation and values above one will speed up the animation. It is also possible to specify a negative multiplier
597  * to play the animation in reverse.
598  *
599  * @method setSpeedFactor
600  * @for Animation
601  * @param {float}  value which will multiply the velocity.
602  * @example
603  *     anim.setSpeedFactor(2);
604  *     anim.play();             // plays the animation twice as fast
605  *
606  *
607  *     anim.setSpeedFactor(0.5);
608  *     anim.play();             // plays the animation half speed
609  *
610  */
611 void AnimationApi::SetSpeedFactor( const v8::FunctionCallbackInfo< v8::Value >& args )
612 {
613   v8::Isolate* isolate = args.GetIsolate();
614   v8::HandleScope handleScope( isolate );
615
616   Animation anim = GetAnimation( isolate, args );
617
618   bool found( false );
619   float speedFactor = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
620   if( !found )
621   {
622     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
623   }
624   else
625   {
626     anim.SetSpeedFactor( speedFactor );
627   }
628
629 }
630
631 /**
632  * Retrieve the speed factor of the animation
633  *
634  *
635  * @method getSpeedFactor
636  * @for Animation
637  * @return {float} speed factor
638  */
639 void AnimationApi::GetSpeedFactor( const v8::FunctionCallbackInfo< v8::Value >& args )
640 {
641   v8::Isolate* isolate = args.GetIsolate();
642   v8::HandleScope handleScope( isolate );
643
644   Animation anim = GetAnimation( isolate, args );
645
646   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetSpeedFactor() ) );
647 }
648
649 /**
650  * Set the playing range.
651  * Animation will play between the values specified.
652  * Both values ( range.x and range.y ) should be between 0-1,
653  * otherwise they will be ignored.
654  * If the range provided is not in proper order ( minimum,maximum), it will be reordered.
655  * @method setPlayRange
656  * @for Animation
657  * @param {Object} Range
658  * @param {Float} Range.start
659  * @param {Float} Range.end
660  * @example
661  *     var range = {  start:0.1, end:0.6 };
662  *     anim.setPlayRange( range );
663  */
664 void AnimationApi::SetPlayRange( const v8::FunctionCallbackInfo< v8::Value >& args )
665 {
666   v8::Isolate* isolate = args.GetIsolate();
667   v8::HandleScope handleScope( isolate );
668
669   Animation anim = GetAnimation( isolate, args );
670   Vector2 range(0,0);
671
672   if( args.Length() != 1 )
673   {
674     DALI_SCRIPT_EXCEPTION( isolate, "missing / invalid parameters" );
675     return;
676   }
677   v8::Local<v8::Value > rangeValue = args[0];
678   if( !rangeValue->IsObject() )
679   {
680     DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters" );
681     return;
682   }
683   v8::Local<v8::Object> obj = rangeValue->ToObject();
684   v8::Local<v8::Value> startValue = obj->Get( v8::String::NewFromUtf8( isolate, "start" ) );
685   v8::Local<v8::Value> endValue = obj->Get( v8::String::NewFromUtf8( isolate, "end" ) );
686
687   if( startValue->IsNumber() &&  endValue->IsNumber())
688   {
689         range.x= startValue->ToNumber()->Value();
690         range.y = endValue->ToNumber()->Value();
691   }
692   else
693   {
694     DALI_SCRIPT_EXCEPTION( isolate, "missing start/end value" );
695     return;
696   }
697
698   anim.SetPlayRange( range );
699
700 }
701
702 /**
703  * Get the playing range.
704  * @method getPlayRange
705  * @for Animation
706  * @return {Object} Range with { start: ,  end: } properties.
707  */
708 void AnimationApi::GetPlayRange( const v8::FunctionCallbackInfo< v8::Value >& args )
709 {
710   v8::Isolate* isolate = args.GetIsolate();
711   v8::EscapableHandleScope handleScope( isolate );
712   Animation anim = GetAnimation( isolate, args );
713
714
715   v8::Local<v8::Object> rangeObject = v8::Object::New( isolate );
716
717   Vector2 range = anim.GetPlayRange();
718
719  // set device id
720   rangeObject->Set( v8::String::NewFromUtf8( isolate, "start"), v8::Number::New( isolate,range.x ));
721
722    // set state
723   rangeObject->Set( v8::String::NewFromUtf8( isolate, "end"), v8::Number::New( isolate,range.y ));
724
725   args.GetReturnValue().Set( rangeObject );
726 }
727
728
729 /**
730  * Sets the progress of the animation.
731  * The animation will play (or continue playing) from this point. The progress
732  * must be in the 0-1 interval or in the play range interval if defined ( See SetPlayRange ),
733  * otherwise, it will be ignored.
734  *
735  * @method setCurrentProgress
736  * @for Animation
737  * @param {float}  progress The new progress as a normalized value between [0,1] or between the
738  * play range if specified.
739  */
740 void AnimationApi::SetCurrentProgress( const v8::FunctionCallbackInfo< v8::Value >& args )
741 {
742   v8::Isolate* isolate = args.GetIsolate();
743   v8::HandleScope handleScope( isolate );
744
745   Animation anim = GetAnimation( isolate, args );
746
747   bool found( false );
748
749   float progress = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
750   if( !found )
751   {
752     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
753     return;
754   }
755   anim.SetCurrentProgress( progress );
756
757 }
758
759 /**
760  *
761  *  Play the animation from a given point.
762  * The progress must be in the 0-1 interval or in the play range interval if defined ( See SetPlayRange ),
763  * otherwise, it will be ignored.
764  * @method playFrom
765  * @for Animation
766  * @param {float} progress A value between [0,1], or between the play range if specified, form where the animation should start playing
767  */
768 void AnimationApi::PlayFrom( const v8::FunctionCallbackInfo< v8::Value >& args )
769 {
770   v8::Isolate* isolate = args.GetIsolate();
771   v8::HandleScope handleScope( isolate );
772
773   Animation anim = GetAnimation( isolate, args );
774
775   bool found( false );
776
777   float progress = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
778   if( !found )
779   {
780     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
781     return;
782   }
783   anim.PlayFrom( progress );
784
785 }
786
787 /**
788  * Play the animation
789  * @method play
790  * @for Animation
791  */
792 void AnimationApi::Play( const v8::FunctionCallbackInfo<v8::Value>& args )
793 {
794   v8::Isolate* isolate = args.GetIsolate();
795   v8::HandleScope handleScope( isolate );
796
797   Animation anim = GetAnimation( isolate, args );
798   anim.Play();
799 }
800 /**
801  * Pause the animation
802  * @method pause
803  * @for Animation
804  */
805 void AnimationApi::Pause( const v8::FunctionCallbackInfo<v8::Value>& args )
806 {
807   v8::Isolate* isolate = args.GetIsolate();
808   v8::HandleScope handleScope( isolate );
809
810   Animation anim = GetAnimation( isolate, args );
811   anim.Pause();
812 }
813 /**
814  * Stop the animation
815  * @method stop
816  * @for Animation
817  */
818 void AnimationApi::Stop( const v8::FunctionCallbackInfo<v8::Value>& args )
819 {
820   v8::Isolate* isolate = args.GetIsolate();
821   v8::HandleScope handleScope( isolate );
822
823   Animation anim = GetAnimation( isolate, args );
824   anim.Stop();
825 }
826 /**
827  * Clear the animation
828  * This disconnects any objects that were being animated, effectively stopping the animation.
829  * @method clear
830  * @for Animation
831  */
832 void AnimationApi::Clear( const v8::FunctionCallbackInfo<v8::Value>& args )
833 {
834   v8::Isolate* isolate = args.GetIsolate();
835   v8::HandleScope handleScope( isolate );
836
837   Animation anim = GetAnimation( isolate, args );
838   anim.Clear();
839 }
840
841
842 void AnimationApi::Animate( const v8::FunctionCallbackInfo<v8::Value>& args )
843 {
844   v8::Isolate* isolate = args.GetIsolate();
845   v8::HandleScope handleScope( isolate );
846
847   Animation anim = GetAnimation( isolate, args );
848   AnimationParameters animParams( anim );
849   bool found(false);
850
851   //Get actor
852   Dali::Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
853   if( !found )
854   {
855     DALI_SCRIPT_EXCEPTION( isolate, "Missing actor parameter");
856     return;
857   }
858
859   //Get path
860   Dali::Path path;
861   BaseWrappedObject* wrapper = V8Utils::GetWrappedDaliObjectParameter( PARAMETER_1, BaseWrappedObject::PATH, isolate, args);
862   PathWrapper* pathWrapper = static_cast< PathWrapper*>( wrapper );
863   if( !pathWrapper )
864   {
865     return;
866   }
867   path = pathWrapper->GetPath();
868
869   //Get forward vector
870   bool bFound(false);
871   Vector3 forward = V8Utils::GetVector3Parameter( PARAMETER_2, bFound, isolate, args );
872   if( !bFound )
873   {
874     return;
875   }
876
877   //Get animation options
878   GetAnimationOptions( isolate, args[3], animParams );
879   if( animParams.optionsFound )
880   {
881     anim.Animate( actor, path, forward, animParams.alphaFunction, TimePeriod( animParams.delay, animParams.duration) );
882   }
883   else
884   {
885     anim.Animate( actor, path, forward );
886   }
887 }
888
889 /**
890  *
891  * Animate a property value by a relative amount.
892  *
893  * The effect will start & end when the animation begins & ends.
894  * @method animateBy
895  * @for Animation
896  * @param {Object} target object that contains a property to be animated (e.g. myActor )
897  * @param {String} property name (e.g. "position" )
898  * @param {Object} relativeValue The property value will change by this amount.
899  * @param {Object} [options] Animation options.
900  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
901  * @param {Float} [options.duration] duration of the animation
902  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
903  *
904  * @example
905  *
906  *     // animation x position
907  *     var anim = new dali.Animation( 1 );
908  *     anim.animateBy( imageActor,"positionX", 30 );
909  *     anim.play();
910  *
911  *     // animate x,y,z position with the optional animation options
912  *     var options = {
913  *        delay: 3,     // 3 second delay before starting
914  *        duration: 5,  // 5 second duration
915  *        alpha:"easeInOutSine"   // Speeds up and slows to a gradual stop
916  *     }
917  *
918  *     anim.animateBy( imageActor,"position", [100,200,0], options );
919  *
920  */
921 void AnimationApi::AnimateBy( const v8::FunctionCallbackInfo<v8::Value>& args )
922 {
923   v8::Isolate* isolate = args.GetIsolate();
924   v8::HandleScope handleScope( isolate );
925
926   Animation anim = GetAnimation( isolate, args );
927   AnimationParameters animParams( anim );
928
929   // grab all the parameters
930   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::PROPERTY_VALUE);
931   if( !ok )
932   {
933     // GetAnimationParameters will log
934     return;
935   }
936
937   if( animParams.optionsFound )
938   {
939     anim.AnimateBy( Property( animParams.target, animParams.propertyIndex ),
940                               animParams.value,
941                               animParams.alphaFunction,
942                               TimePeriod( animParams.delay, animParams.duration) );
943   }
944   else
945   {
946     anim.AnimateBy( Property( animParams.target, animParams.propertyIndex ), animParams.value );
947   }
948
949 }
950
951 /**
952  *
953  * Animate a property to a destination value.
954  *
955  * The effect will start & end when the animation begins & ends.
956  * @method animateTo
957  * @for Animation
958  * @param {Object} target object that contains a property to be animated (e.g. myActor )
959  * @param {String} property name (e.g. "position" )
960  * @param {Object} destinationValue The property value will changed to this value
961  * @param {Object} [options] Animation options.
962  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
963  * @param {Float} [options.duration] duration of the animation
964  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
965  *
966  * @example
967  *
968  *     var anim = new dali.Animation( 1 );
969  *     anim.animateTo( imageActor,"positionX", 30 );
970  *     anim.play();
971  *
972  *
973  *     // with the optional animation options object
974  *     var options = {
975  *        delay: 3,     // 3 second delay before starting
976  *        duration: 5,  // 5 second duration
977  *        alpha:"easeInOutSine"   // Speeds up and slows to a gradual stop
978  *     }
979  *
980  *     anim.animateTo( imageActor,"position", [100,200,0], options );
981  *
982  */
983 void AnimationApi::AnimateTo( const v8::FunctionCallbackInfo< v8::Value >& args )
984 {
985   v8::Isolate* isolate = args.GetIsolate();
986   v8::HandleScope handleScope( isolate );
987
988   Animation anim = GetAnimation( isolate, args );
989   AnimationParameters animParams( anim );
990
991   // grab all the parameters
992   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::PROPERTY_VALUE );
993   if( !ok )
994   {
995     // GetAnimationParameters will log
996     return;
997   }
998
999   if( animParams.optionsFound )
1000   {
1001
1002     anim.AnimateTo( Property( animParams.target,animParams.propertyIndex ),
1003                                   animParams.value,
1004                                   animParams.alphaFunction,
1005                                   TimePeriod( animParams.delay, animParams.duration) );
1006   }
1007   else
1008   {
1009     anim.AnimateTo( Property( animParams.target, animParams.propertyIndex ), animParams.value );
1010   }
1011 }
1012
1013 /**
1014  *
1015  * Animate a property between keyframes.
1016  *
1017  * The effect will start & end when the animation begins & ends.
1018  * @method animateBetween
1019  * @for Animation
1020  * @param {Object} target object that contains a property to be animated (e.g. myActor )
1021  * @param {String} property name (e.g. "position" )
1022  * @param {Object} keyframes array of keyframe objects
1023  * @param {Object} [options] Animation options.
1024  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
1025  * @param {Float} [options.duration] duration of the animation
1026  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
1027  *
1028  *
1029  * @example
1030  *
1031  *  create some keyframes to move an actor around a square, and return to the start
1032  * </br >
1033  *  <img src="../assets/img/animation/keyframe-animation.png">
1034  *
1035  *
1036  *     var keyframes = [
1037  *     {
1038  *       progress:0.0,
1039  *       value: [0,0,0]
1040  *     },
1041  *     {
1042  *       progress:0.25,
1043  *       value: [500,0,0]
1044  *     },
1045  *
1046  *     {
1047  *       progress:0.5,
1048  *       value: [500,500,0]
1049  *     },
1050  *     {
1051  *       progress:0.75,
1052  *       value: [0,500,0]
1053  *     },
1054  *     {
1055  *       progress:1.0,
1056  *       value: [0,0,0]
1057  *     } ];
1058  *
1059  *
1060  *     anim.animateBetween( imageActor,"position", keyframes );
1061  *
1062  */
1063 void AnimationApi::AnimateBetween( const v8::FunctionCallbackInfo< v8::Value >& args )
1064 {
1065   v8::Isolate* isolate = args.GetIsolate();
1066   v8::HandleScope handleScope( isolate );
1067
1068   Animation anim = GetAnimation( isolate, args );
1069   AnimationParameters animParams( anim );
1070
1071   // grab all the parameters
1072   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::KEYFRAMES );
1073   if( !ok )
1074   {
1075     // GetAnimationParameters will log
1076     return;
1077   }
1078
1079   // if animation options exist...
1080   if( animParams.optionsFound )
1081   {
1082
1083     anim.AnimateBetween( Property( animParams.target,animParams.propertyIndex ),
1084                                   animParams.keyFrames,
1085                                   animParams.alphaFunction,
1086                                   TimePeriod( animParams.delay, animParams.duration) );
1087   }
1088   else
1089   {
1090     anim.AnimateBetween( Property( animParams.target, animParams.propertyIndex ), animParams.keyFrames );
1091   }
1092 }
1093
1094 /**
1095  * show an actor during the animation.
1096  *
1097  * This is a helper, which simulates animating the visibility property of an actor
1098  * with zero duration ( it is just a boolean).
1099  * e.g. it performs  anim.AnimateTo( actor,"visible",true, { delay:delay: duration:0 } );
1100  * @method show
1101  * @for Animation
1102  * @param {Object} Actor
1103  * @param {float} delay until the actor is shown
1104  */
1105 void AnimationApi::Show( const v8::FunctionCallbackInfo< v8::Value >& args )
1106 {
1107   v8::Isolate* isolate = args.GetIsolate();
1108   v8::HandleScope handleScope( isolate );
1109   Animation anim = GetAnimation( isolate, args );
1110   bool found( false );
1111
1112   Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
1113   if( !found)
1114   {
1115     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 actor" );
1116     return;
1117   }
1118   // get the duration
1119   float delay = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 1.f /* default */);
1120   if( !found )
1121   {
1122     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 delay" );
1123     return;
1124   }
1125   anim.Show( actor, delay );
1126
1127 }
1128
1129 /**
1130  * hide an actor during the animation.
1131  *
1132  * This is a helper, which simulates animating the visibility property of an actor
1133  * with zero duration ( it is just a boolean).
1134  * e.g. it performs  anim.AnimateTo( actor,"visible",false, { delay:delay: duration:0 } );
1135  * @method hide
1136  * @for Animation
1137  * @param {Object} Actor
1138  * @param {float} delay until the actor is hidden
1139  */
1140 void AnimationApi::Hide( const v8::FunctionCallbackInfo< v8::Value >& args )
1141 {
1142   v8::Isolate* isolate = args.GetIsolate();
1143   v8::HandleScope handleScope( isolate );
1144   Animation anim = GetAnimation( isolate, args );
1145   bool found( false );
1146   Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
1147   if( !found )
1148   {
1149     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 actor" );
1150     return;
1151   }
1152
1153   // get the duration
1154   float delay = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 1.f /* default */);
1155   if( !found )
1156   {
1157     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 delay" );
1158     return;
1159   }
1160   anim.Hide( actor, delay );
1161 }
1162
1163
1164
1165
1166 } // namespace V8Plugin
1167
1168 } // namespace Dali