Merge "Added Animation loop count" into devel/master
[platform/core/uifw/dali-core.git] / dali / devel-api / scripting / scripting.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 <dali/devel-api/scripting/scripting.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/actors/actor.h>
23 #include <dali/public-api/images/resource-image.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/object/property-array.h>
26 #include <dali/internal/common/image-attributes.h>
27 #include <dali/internal/event/images/resource-image-impl.h>
28 #include <dali/internal/event/images/frame-buffer-image-impl.h>
29 #include <dali/internal/event/images/buffer-image-impl.h>
30 #include <dali/internal/event/effects/shader-effect-impl.h>
31
32 namespace Dali
33 {
34
35 namespace Scripting
36 {
37
38 namespace
39 {
40
41 // Tables used here for converting strings to the enumerations and vice versa
42 struct AnchorValue
43 {
44   const char* name;
45   const Vector3 value;
46 };
47 const AnchorValue ANCHOR_CONSTANT_TABLE[] =
48 {
49   { "TOP_LEFT",               ParentOrigin::TOP_LEFT               },
50   { "TOP_CENTER",             ParentOrigin::TOP_CENTER             },
51   { "TOP_RIGHT",              ParentOrigin::TOP_RIGHT              },
52   { "CENTER_LEFT",            ParentOrigin::CENTER_LEFT            },
53   { "CENTER",                 ParentOrigin::CENTER                 },
54   { "CENTER_RIGHT",           ParentOrigin::CENTER_RIGHT           },
55   { "BOTTOM_LEFT",            ParentOrigin::BOTTOM_LEFT            },
56   { "BOTTOM_CENTER",          ParentOrigin::BOTTOM_CENTER          },
57   { "BOTTOM_RIGHT",           ParentOrigin::BOTTOM_RIGHT           },
58 };
59 const unsigned int ANCHOR_CONSTANT_TABLE_COUNT = sizeof( ANCHOR_CONSTANT_TABLE ) / sizeof( ANCHOR_CONSTANT_TABLE[0] );
60
61 const StringEnum COLOR_MODE_TABLE[] =
62 {
63   { "USE_OWN_COLOR",                    USE_OWN_COLOR                    },
64   { "USE_PARENT_COLOR",                 USE_PARENT_COLOR                 },
65   { "USE_OWN_MULTIPLY_PARENT_COLOR",    USE_OWN_MULTIPLY_PARENT_COLOR    },
66   { "USE_OWN_MULTIPLY_PARENT_ALPHA",    USE_OWN_MULTIPLY_PARENT_ALPHA    },
67 };
68 const unsigned int COLOR_MODE_TABLE_COUNT = sizeof( COLOR_MODE_TABLE ) / sizeof( COLOR_MODE_TABLE[0] );
69
70 const StringEnum POSITION_INHERITANCE_MODE_TABLE[] =
71 {
72   { "INHERIT_PARENT_POSITION",                    INHERIT_PARENT_POSITION                    },
73   { "USE_PARENT_POSITION",                        USE_PARENT_POSITION                        },
74   { "USE_PARENT_POSITION_PLUS_LOCAL_POSITION",    USE_PARENT_POSITION_PLUS_LOCAL_POSITION    },
75   { "DONT_INHERIT_POSITION",                      DONT_INHERIT_POSITION                      },
76 };
77 const unsigned int POSITION_INHERITANCE_MODE_TABLE_COUNT = sizeof( POSITION_INHERITANCE_MODE_TABLE ) / sizeof( POSITION_INHERITANCE_MODE_TABLE[0] );
78
79 const StringEnum DRAW_MODE_TABLE[] =
80 {
81   { "NORMAL",     DrawMode::NORMAL     },
82   { "OVERLAY_2D", DrawMode::OVERLAY_2D },
83   { "STENCIL",    DrawMode::STENCIL    },
84 };
85 const unsigned int DRAW_MODE_TABLE_COUNT = sizeof( DRAW_MODE_TABLE ) / sizeof( DRAW_MODE_TABLE[0] );
86
87 const StringEnum IMAGE_LOAD_POLICY_TABLE[] =
88 {
89   { "IMMEDIATE", ResourceImage::IMMEDIATE },
90   { "ON_DEMAND", ResourceImage::ON_DEMAND },
91 };
92 const unsigned int IMAGE_LOAD_POLICY_TABLE_COUNT = sizeof( IMAGE_LOAD_POLICY_TABLE ) / sizeof( IMAGE_LOAD_POLICY_TABLE[0] );
93
94 const StringEnum IMAGE_RELEASE_POLICY_TABLE[] =
95 {
96   { "UNUSED", Image::UNUSED },
97   { "NEVER",  Image::NEVER  },
98 };
99 const unsigned int IMAGE_RELEASE_POLICY_TABLE_COUNT = sizeof( IMAGE_RELEASE_POLICY_TABLE ) / sizeof( IMAGE_RELEASE_POLICY_TABLE[0] );
100
101 const StringEnum PIXEL_FORMAT_TABLE[] =
102 {
103   { "A8",                                           Pixel::A8                                           },
104   { "L8",                                           Pixel::L8                                           },
105   { "LA88",                                         Pixel::LA88                                         },
106   { "RGB565",                                       Pixel::RGB565                                       },
107   { "BGR565",                                       Pixel::BGR565                                       },
108   { "RGBA4444",                                     Pixel::RGBA4444                                     },
109   { "BGRA4444",                                     Pixel::BGRA4444                                     },
110   { "RGBA5551",                                     Pixel::RGBA5551                                     },
111   { "BGRA5551",                                     Pixel::BGRA5551                                     },
112   { "RGB888",                                       Pixel::RGB888                                       },
113   { "RGB8888",                                      Pixel::RGB8888                                      },
114   { "BGR8888",                                      Pixel::BGR8888                                      },
115   { "RGBA8888",                                     Pixel::RGBA8888                                     },
116   { "BGRA8888",                                     Pixel::BGRA8888                                     },
117   { "COMPRESSED_R11_EAC",                           Pixel::COMPRESSED_R11_EAC                           },
118   { "COMPRESSED_SIGNED_R11_EAC",                    Pixel::COMPRESSED_SIGNED_R11_EAC                    },
119   { "COMPRESSED_SIGNED_RG11_EAC",                   Pixel::COMPRESSED_SIGNED_RG11_EAC                   },
120   { "COMPRESSED_RG11_EAC",                          Pixel::COMPRESSED_RG11_EAC                          },
121   { "COMPRESSED_RGB8_ETC2",                         Pixel::COMPRESSED_RGB8_ETC2                         },
122   { "COMPRESSED_SRGB8_ETC2",                        Pixel::COMPRESSED_SRGB8_ETC2                        },
123   { "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",     Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2     },
124   { "COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",    Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2    },
125   { "COMPRESSED_RGBA8_ETC2_EAC",                    Pixel::COMPRESSED_RGBA8_ETC2_EAC                    },
126   { "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",             Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC             },
127   { "COMPRESSED_RGB8_ETC1",                         Pixel::COMPRESSED_RGB8_ETC1                         },
128   { "COMPRESSED_RGB_PVRTC_4BPPV1",                  Pixel::COMPRESSED_RGB_PVRTC_4BPPV1                  },
129 };
130 const unsigned int PIXEL_FORMAT_TABLE_COUNT = sizeof( PIXEL_FORMAT_TABLE ) / sizeof( PIXEL_FORMAT_TABLE[0] );
131
132 const StringEnum IMAGE_FITTING_MODE_TABLE[] =
133 {
134   { "SHRINK_TO_FIT", FittingMode::SHRINK_TO_FIT },
135   { "SCALE_TO_FILL", FittingMode::SCALE_TO_FILL },
136   { "FIT_WIDTH",     FittingMode::FIT_WIDTH    },
137   { "FIT_HEIGHT",    FittingMode::FIT_HEIGHT   },
138 };
139 const unsigned int IMAGE_FITTING_MODE_TABLE_COUNT = sizeof( IMAGE_FITTING_MODE_TABLE ) / sizeof( IMAGE_FITTING_MODE_TABLE[0] );
140
141 const StringEnum IMAGE_SAMPLING_MODE_TABLE[] =
142 {
143   { "BOX",              SamplingMode::BOX            },
144   { "NEAREST",          SamplingMode::NEAREST        },
145   { "LINEAR",           SamplingMode::LINEAR         },
146   { "BOX_THEN_NEAREST", SamplingMode::BOX_THEN_NEAREST },
147   { "BOX_THEN_LINEAR",  SamplingMode::BOX_THEN_LINEAR  },
148   { "NO_FILTER",        SamplingMode::NO_FILTER       },
149   { "DONT_CARE",        SamplingMode::DONT_CARE       },
150 };
151 const unsigned int IMAGE_SAMPLING_MODE_TABLE_COUNT = sizeof( IMAGE_SAMPLING_MODE_TABLE ) / sizeof( IMAGE_SAMPLING_MODE_TABLE[0] );
152
153 const char* ImageTypeName[] = { "ResourceImage", "FrameBufferImage", "BufferImage" };
154 enum ImageType                { RESOURCE_IMAGE,  FRAME_BUFFER_IMAGE, BUFFER_IMAGE };
155 const unsigned int imageTypeCount = sizeof( ImageTypeName ) / sizeof( const char* );
156
157 bool CompareEnums( const char * a, const char * b, size_t& size )
158 {
159   size = 0;
160   while( ( *a != '\0' ) && ( *b != '\0' ) && ( *a != ',') && ( *b != ',') )
161   {
162     ++size;
163     char ca = *a;
164     char cb = *b;
165
166     if( ( ( ca == '-' ) || ( ca == '_') ) &&
167         ( ( cb == '-' ) || ( cb == '_') ) )
168     {
169       ++a;
170       ++b;
171       continue;
172     }
173
174     if( ( 'A' <= ca ) && ( ca <= 'Z') )
175     {
176       ca = ca + ( 'a' - 'A' );
177     }
178
179     if( ( 'A' <= cb ) && ( cb <= 'Z') )
180     {
181       cb = cb + ( 'a' - 'A' );
182     }
183
184     if( ca != cb )
185     {
186       return false;
187     }
188
189     ++a;
190     ++b;
191   }
192
193   // enums can be comma separated so check ends and comma
194   if( ( ( *a == '\0' ) && ( *b == '\0' ) ) ||
195       ( ( *a == '\0' ) && ( *b == ','  ) ) ||
196       ( ( *a == ','  ) && ( *b == '\0' ) ) )
197   {
198     return true;
199   }
200
201   return false;
202 }
203
204 } // unnamed namespace
205
206 bool EnumStringToInteger( const char * const value, const StringEnum* const enumTable, unsigned int tableCount, unsigned int& integerEnum )
207 {
208   unsigned int ret = 0;
209
210   bool found = false;
211   bool done = false;
212
213   if( value && enumTable && tableCount )
214   {
215     const char* pValue = value;
216
217     while(!done)
218     {
219       size_t size = 0;
220
221       const StringEnum* table = enumTable;
222
223       for ( unsigned int i = 0; i < tableCount; ++i )
224       {
225         if( CompareEnums( pValue, table->string, size ) )
226         {
227           found = true;
228           ret |= table->value;
229           break;
230         }
231         table++;
232       }
233
234       done = true;
235
236       if(found)
237       {
238         // allow comma separated or'd value
239         if( *(pValue+size) == ',' )
240         {
241           pValue += size + 1;
242           done = false;
243         }
244       }
245
246     }
247
248     integerEnum = ret;
249   }
250
251   if ( !found )
252   {
253     DALI_LOG_ERROR( "Unknown enumeration string %s\n", value );
254   }
255   return found;
256 }
257
258 unsigned int FindEnumIndex( const char* value, const StringEnum* table, unsigned int tableCount )
259 {
260   unsigned int index = 0;
261   bool found = false;
262   for ( unsigned int i = 0; i < tableCount; ++i, ++index )
263   {
264     size_t sizeIgnored = 0;
265     if( CompareEnums( value, table->string, sizeIgnored ) )
266     {
267       found = true;
268       break;
269     }
270     ++table;
271   }
272   if ( !found )
273   {
274     DALI_LOG_ERROR( "Unknown enumeration string %s\n", value );
275   }
276   return index;
277 }
278
279 ColorMode GetColorMode( const std::string& value )
280 {
281   // return default on error
282   ColorMode mode( USE_OWN_MULTIPLY_PARENT_ALPHA );
283   GetEnumeration< ColorMode >( value.c_str(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode );
284   return mode;
285 }
286
287
288 std::string GetColorMode( ColorMode value )
289 {
290   const char* name = GetEnumerationName< ColorMode >( value, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
291   if( name )
292   {
293     return std::string( name );
294   }
295   return std::string();
296 }
297
298 PositionInheritanceMode GetPositionInheritanceMode( const std::string& value )
299 {
300   // return default on error
301   PositionInheritanceMode mode( INHERIT_PARENT_POSITION );
302   GetEnumeration< PositionInheritanceMode >( value.c_str(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode );
303   return mode;
304 }
305
306
307 std::string GetPositionInheritanceMode( PositionInheritanceMode value )
308 {
309   const char* name = GetEnumerationName< PositionInheritanceMode >( value, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
310   if( name )
311   {
312     return std::string( name );
313   }
314   return std::string();
315 }
316
317
318 DrawMode::Type GetDrawMode( const std::string& value )
319 {
320   // return default on error
321   DrawMode::Type mode( DrawMode::NORMAL );
322   GetEnumeration< DrawMode::Type >( value.c_str(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode );
323   return mode;
324 }
325
326
327 std::string GetDrawMode( DrawMode::Type value )
328 {
329   const char* name = GetEnumerationName< DrawMode::Type >( value, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
330   if( name )
331   {
332     return std::string( name );
333   }
334   return std::string();
335 }
336
337
338 Vector3 GetAnchorConstant( const std::string& value )
339 {
340   for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
341   {
342     size_t sizeIgnored = 0;
343     if( CompareEnums( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) )
344     {
345       return ANCHOR_CONSTANT_TABLE[ i ].value;
346     }
347   }
348   return Vector3();
349 }
350
351
352 Image NewImage( const Property::Value& property )
353 {
354   Image ret;
355
356   std::string filename;
357   ResourceImage::LoadPolicy loadPolicy = Dali::Internal::IMAGE_LOAD_POLICY_DEFAULT;
358   Image::ReleasePolicy releasePolicy   = Dali::Internal::IMAGE_RELEASE_POLICY_DEFAULT;
359   Internal::ImageAttributes attributes = Internal::ImageAttributes::New();
360
361   const Property::Map* map = property.GetMap();
362   ImageType imageType = RESOURCE_IMAGE; // default to resource image
363   if( map )
364   {
365     // first check the type as it determines, which other parameters are needed
366     const Property::Value* value = map->Find( "type" );
367     if( value )
368     {
369       std::string type;
370       value->Get( type );
371       for( unsigned int i = 0; i < imageTypeCount; ++i )
372       {
373         if( 0 == type.compare( ImageTypeName[ i ] ) )
374         {
375           imageType = static_cast<ImageType>( i );
376           break;
377         }
378       }
379     }
380
381     // filename is only needed for resource images
382     if( RESOURCE_IMAGE == imageType )
383     {
384       const Property::Value* value = map->Find( "filename" );
385       if( value )
386       {
387         value->Get( filename );
388       }
389       // if empty file, no need to go further
390       if( filename.size() == 0 )
391       {
392         DALI_LOG_ERROR( "No filename\n" );
393         return Image();
394       }
395     }
396
397     value = map->Find( "loadPolicy" );
398     if( value )
399     {
400       std::string policy;
401       value->Get( policy );
402       // keep default value on error
403       GetEnumeration< ResourceImage::LoadPolicy >( policy.c_str(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT, loadPolicy );
404     }
405
406     value = map->Find( "releasePolicy" );
407     if( value )
408     {
409       std::string policy;
410       value->Get( policy );
411       // keep default value on error
412       GetEnumeration< Image::ReleasePolicy >( policy.c_str(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT, releasePolicy );
413     }
414
415     // Width and height can be set individually. Dali derives the unspecified
416     // dimension from the aspect ratio of the raw image.
417     int width = 0, height = 0;
418
419     value = map->Find( "width" );
420     if( value )
421     {
422       // handle floats and integer the same for json script
423       if( value->GetType() == Property::FLOAT )
424       {
425         width = static_cast<unsigned int>( value->Get<float>() );
426       }
427       else
428       {
429         value->Get( width );
430       }
431     }
432     value = map->Find( "height" );
433     if( value )
434     {
435       if( value->GetType() == Property::FLOAT )
436       {
437         height = static_cast<int>( value->Get<float>() );
438       }
439       else
440       {
441         value->Get( height );
442       }
443     }
444     attributes.SetSize( width, height );
445
446     Pixel::Format pixelFormat = Pixel::RGBA8888;
447     value = map->Find( "pixelFormat" );
448     if( value )
449     {
450       std::string format;
451       value->Get( format );
452       GetEnumeration< Pixel::Format >( format.c_str(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT, pixelFormat );
453     }
454
455     value = map->Find( "fittingMode" );
456     if( value )
457     {
458       std::string fitting;
459       value->Get( fitting );
460       FittingMode::Type mode;
461       if( GetEnumeration< FittingMode::Type >( fitting.c_str(), IMAGE_FITTING_MODE_TABLE, IMAGE_FITTING_MODE_TABLE_COUNT, mode ) )
462       {
463         attributes.SetScalingMode( mode );
464       }
465     }
466
467     value = map->Find( "samplingMode" );
468     if( value )
469     {
470       std::string sampling;
471       value->Get( sampling );
472       SamplingMode::Type mode;
473       if( GetEnumeration< SamplingMode::Type >( sampling.c_str(), IMAGE_SAMPLING_MODE_TABLE, IMAGE_SAMPLING_MODE_TABLE_COUNT, mode ) )
474       {
475         attributes.SetFilterMode( mode );
476       }
477     }
478
479     value = map->Find( "orientation" );
480     if( value )
481     {
482       bool b = value->Get<bool>();
483       attributes.SetOrientationCorrection( b );
484     }
485
486     switch( imageType )
487     {
488       case RESOURCE_IMAGE :
489       {
490         ret = ResourceImage::New( filename, loadPolicy, releasePolicy,
491                                   ImageDimensions( attributes.GetSize().x, attributes.GetSize().y ),
492                                   attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() );
493         break;
494       }
495       case BUFFER_IMAGE :
496       {
497         ret = BufferImage::New( attributes.GetWidth(),
498                                 attributes.GetHeight(),
499                                 pixelFormat,
500                                 releasePolicy );
501         break;
502       }
503       case FRAME_BUFFER_IMAGE :
504       {
505         ret = FrameBufferImage::New( attributes.GetWidth(),
506                                      attributes.GetHeight(),
507                                      pixelFormat,
508                                      releasePolicy );
509         break;
510       }
511     }
512   }
513
514   return ret;
515
516 } // Image NewImage( Property::Value map )
517
518
519 ShaderEffect NewShaderEffect( const Property::Value& property )
520 {
521   Internal::ShaderEffectPtr ret;
522
523   const Property::Map* map = property.GetMap();
524   if( map )
525   {
526     ret = Internal::ShaderEffect::New( Dali::ShaderEffect::HINT_NONE ); // hint can be reset if in map
527
528     const Property::Value* value = map->Find( "program" );
529     if( value )
530     {
531       Property::Index index = ret->GetPropertyIndex( "program" );
532       ret->SetProperty( index, *value );
533     }
534
535     for( unsigned int i = 0; i < map->Count(); ++i )
536     {
537       const std::string& key = map->GetKey( i );
538       if( key != "program" )
539       {
540         Property::Index index = ret->GetPropertyIndex( key );
541
542         const Property::Value& value = map->GetValue( i );
543         if( Property::INVALID_INDEX != index )
544         {
545           ret->SetProperty( index, value );
546         }
547         else
548         {
549           // if its not a property then register it as a uniform (making a custom property)
550           if( value.GetType() == Property::INTEGER )
551           {
552             // valid uniforms are floats, vec3's etc so we recast if the user accidentally
553             // set as integer. Note the map could have come from json script.
554             Property::Value asFloat( static_cast<float>( value.Get<int>() ) );
555             ret->SetUniform( key, asFloat, Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
556           }
557           else
558           {
559             ret->SetUniform( key, value, Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
560           }
561         }
562       }
563     }
564   }
565
566   return Dali::ShaderEffect(ret.Get());
567 }
568
569
570 Actor NewActor( const Property::Map& map )
571 {
572   BaseHandle handle;
573
574   // First find type and create Actor
575   Property::Value* typeValue = map.Find( "type" );
576   if ( typeValue )
577   {
578     TypeInfo type = TypeRegistry::Get().GetTypeInfo( typeValue->Get< std::string >() );
579     if ( type )
580     {
581       handle = type.CreateInstance();
582     }
583   }
584
585   if ( !handle )
586   {
587     DALI_LOG_ERROR( "Actor type not provided\n" );
588     return Actor();
589   }
590
591   Actor actor( Actor::DownCast( handle ) );
592
593   if ( actor )
594   {
595     // Now set the properties, or create children
596     for ( unsigned int i = 0, mapCount = map.Count(); i < mapCount; ++i )
597     {
598       const StringValuePair& pair( map.GetPair( i ) );
599       const std::string& key( pair.first );
600       if ( key == "type" )
601       {
602         continue;
603       }
604
605       const Property::Value& value( pair.second );
606
607       if ( key == "actors" )
608       {
609         // Create children
610         Property::Array actorArray = value.Get< Property::Array >();
611         for ( Property::Array::SizeType i = 0; i < actorArray.Size(); ++i)
612         {
613           actor.Add( NewActor( actorArray[i].Get< Property::Map >() ) );
614         }
615       }
616       else if( key ==  "parentOrigin" )
617       {
618         // Parent Origin can be a string constant as well as a Vector3
619
620         const Property::Type type( value.GetType() );
621         if ( type == Property::VECTOR3 )
622         {
623           actor.SetParentOrigin( value.Get< Vector3 >() );
624         }
625         else if( type == Property::STRING )
626         {
627           actor.SetParentOrigin( GetAnchorConstant( value.Get< std::string >() ) );
628         }
629       }
630       else if( key ==  "anchorPoint" )
631       {
632         // Anchor Point can be a string constant as well as a Vector3
633
634         const Property::Type type( value.GetType() );
635         if ( type == Property::VECTOR3 )
636         {
637           actor.SetAnchorPoint( value.Get< Vector3 >() );
638         }
639         else if( type == Property::STRING )
640         {
641           actor.SetAnchorPoint( GetAnchorConstant( value.Get< std::string >() ) );
642         }
643       }
644       else
645       {
646         Property::Index index( actor.GetPropertyIndex( key ) );
647
648         if ( index != Property::INVALID_INDEX )
649         {
650           actor.SetProperty( index, value );
651         }
652       }
653     }
654   }
655
656   return actor;
657 }
658
659 void CreatePropertyMap( Actor actor, Property::Map& map )
660 {
661   map.Clear();
662
663   if ( actor )
664   {
665     map[ "type" ] = actor.GetTypeName();
666
667     // Default properties
668     Property::IndexContainer indices;
669     actor.GetPropertyIndices( indices );
670     const Property::IndexContainer::ConstIterator endIter = indices.End();
671
672     for ( Property::IndexContainer::Iterator iter = indices.Begin(); iter != endIter; ++iter )
673     {
674       map[ actor.GetPropertyName( *iter ) ] = actor.GetProperty( *iter );
675     }
676
677     // Children
678     unsigned int childCount( actor.GetChildCount() );
679     if ( childCount )
680     {
681       Property::Array childArray;
682       for ( unsigned int child = 0; child < childCount; ++child )
683       {
684         Property::Map childMap;
685         CreatePropertyMap( actor.GetChildAt( child ), childMap );
686         childArray.PushBack( childMap );
687       }
688       map[ "actors" ] = childArray;
689     }
690   }
691 }
692
693 void CreatePropertyMap( Image image, Property::Map& map )
694 {
695   map.Clear();
696
697   if ( image )
698   {
699     std::string imageType( "ResourceImage" );
700
701     // Get Type - cannot use TypeRegistry as Image is not an Object and thus, not registered
702     BufferImage bufferImage = BufferImage::DownCast( image );
703     if ( bufferImage )
704     {
705       imageType = "BufferImage";
706       map[ "pixelFormat" ] = GetEnumerationName< Pixel::Format >( bufferImage.GetPixelFormat(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT );
707     }
708     else if ( FrameBufferImage::DownCast( image ) )
709     {
710       imageType = "FrameBufferImage";
711     }
712
713     map[ "type" ] = imageType;
714     map[ "releasePolicy" ] = GetEnumerationName< Image::ReleasePolicy >( image.GetReleasePolicy(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT );
715
716     ResourceImage resourceImage = ResourceImage::DownCast( image );
717     if( resourceImage )
718     {
719       map[ "filename" ] = resourceImage.GetUrl();
720       map[ "loadPolicy" ] = GetEnumerationName< ResourceImage::LoadPolicy >( resourceImage.GetLoadPolicy(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT );
721     }
722
723     int width( image.GetWidth() );
724     int height( image.GetHeight() );
725
726     if ( width && height )
727     {
728       map[ "width" ] = width;
729       map[ "height" ] = height;
730     }
731   }
732 }
733
734 void NewAnimation( const Property::Map& map, Dali::AnimationData& outputAnimationData )
735 {
736   // Note: Builder cannot currently pass generic Property::Maps "{" that are nested, so currently we can only have one AnimateTo per animation.
737   Dali::AnimationData::AnimationDataElement* element = new Dali::AnimationData::AnimationDataElement();
738   element->alphaFunction = AlphaFunction::LINEAR;
739   element->timePeriodDelay = 0.0f;
740   element->timePeriodDuration = 1.0f;
741
742   // Now set the properties, or create children
743   for( unsigned int i = 0, animationMapCount = map.Count(); i < animationMapCount; ++i )
744   {
745     const StringValuePair& pair( map.GetPair( i ) );
746     const std::string& key( pair.first );
747     const Property::Value& value( pair.second );
748
749     if( key == "actor" )
750     {
751       element->actor = value.Get< std::string >();
752     }
753     else if( key == "property" )
754     {
755       element->property = value.Get< std::string >();
756     }
757     else if( key == "value" )
758     {
759       element->value = value;
760     }
761     else if( key == "alphaFunction" )
762     {
763       std::string alphaFunctionValue = value.Get< std::string >();
764
765       if( alphaFunctionValue == "LINEAR" )
766       {
767         element->alphaFunction = AlphaFunction::LINEAR;
768       }
769       else if( alphaFunctionValue == "REVERSE" )
770       {
771         element->alphaFunction = AlphaFunction::REVERSE;
772       }
773       else if( alphaFunctionValue == "EASE_IN_SQUARE" )
774       {
775         element->alphaFunction = AlphaFunction::EASE_IN_SQUARE;
776       }
777       else if( alphaFunctionValue == "EASE_OUT_SQUARE" )
778       {
779         element->alphaFunction = AlphaFunction::EASE_OUT_SQUARE;
780       }
781       else if( alphaFunctionValue == "EASE_IN" )
782       {
783         element->alphaFunction = AlphaFunction::EASE_IN;
784       }
785       else if( alphaFunctionValue == "EASE_OUT" )
786       {
787         element->alphaFunction = AlphaFunction::EASE_OUT;
788       }
789       else if( alphaFunctionValue == "EASE_IN_OUT" )
790       {
791         element->alphaFunction = AlphaFunction::EASE_IN_OUT;
792       }
793       else if( alphaFunctionValue == "EASE_IN_SINE" )
794       {
795         element->alphaFunction = AlphaFunction::EASE_IN_SINE;
796       }
797       else if( alphaFunctionValue == "EASE_OUT_SINE" )
798       {
799         element->alphaFunction = AlphaFunction::EASE_OUT_SINE;
800       }
801       else if( alphaFunctionValue == "EASE_IN_OUT_SINE" )
802       {
803         element->alphaFunction = AlphaFunction::EASE_IN_OUT_SINE;
804       }
805       else if( alphaFunctionValue == "BOUNCE" )
806       {
807         element->alphaFunction = AlphaFunction::BOUNCE;
808       }
809       else if( alphaFunctionValue == "SIN" )
810       {
811         element->alphaFunction = AlphaFunction::SIN;
812       }
813       else if( alphaFunctionValue == "EASE_OUT_BACK" )
814       {
815         element->alphaFunction = AlphaFunction::EASE_OUT_BACK;
816       }
817     }
818     else if( key == "timePeriod" )
819     {
820       Property::Map timeMap = value.Get< Property::Map >();
821       for( unsigned int i = 0; i < timeMap.Count(); ++i )
822       {
823         const StringValuePair& pair( timeMap.GetPair( i ) );
824         if( pair.first == "delay" )
825         {
826           element->timePeriodDelay = pair.second.Get< float >();
827         }
828         else if( pair.first == "duration" )
829         {
830           element->timePeriodDuration = pair.second.Get< float >();
831         }
832       }
833     }
834   }
835
836   outputAnimationData.Add( element );
837 }
838
839 } // namespace scripting
840
841 } // namespace Dali
842
843
844
845