Merge "Implemented the Handle assignment operators properly" into tizen
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / builder / builder-impl.cpp
1 /*
2  * Copyright (c) 2014 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-toolkit/internal/builder/builder-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <sys/stat.h>
23 #include <sstream>
24
25 // INTERNAL INCLUDES
26 #include <dali/dali.h>
27 #include <dali/integration-api/debug.h>
28
29 #include <dali-toolkit/public-api/controls/control.h>
30 #include <dali-toolkit/public-api/builder/json-parser.h>
31
32 #include <dali-toolkit/internal/builder/builder-get-is.inl.h>
33 #include <dali-toolkit/internal/builder/builder-filesystem.h>
34 #include <dali-toolkit/internal/builder/builder-declarations.h>
35 #include <dali-toolkit/internal/builder/replacement.h>
36
37 namespace Dali
38 {
39
40 namespace Toolkit
41 {
42
43 namespace Internal
44 {
45 class Replacement;
46
47 extern Animation CreateAnimation(const TreeNode& child, const Replacement& replacements, const Dali::Actor searchRoot );
48 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value );
49 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value, const Replacement& replacements );
50 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value );
51 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value, const Replacement& replacements );
52 extern Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor);
53 extern Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor);
54 extern Actor SetupActor( const TreeNode& node, Actor& actor, const Replacement& constant );
55
56 #if defined(DEBUG_ENABLED)
57 Integration::Log::Filter* gFilterScript  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_SCRIPT");
58 #endif
59
60 namespace
61 {
62
63 const std::string KEYNAME_STYLES    = "styles";
64 const std::string KEYNAME_TYPE      = "type";
65 const std::string KEYNAME_ACTORS    = "actors";
66 const std::string KEYNAME_SIGNALS   = "signals";
67 const std::string KEYNAME_NAME      = "name";
68 const std::string KEYNAME_TEMPLATES = "templates";
69 const std::string KEYNAME_INCLUDES  = "includes";
70
71 typedef std::vector<const TreeNode*> TreeNodeList;
72
73 template <typename T>
74 std::string ToString(const T& value)
75 {
76   std::stringstream ss;
77   ss << value;
78   return ss.str();
79 }
80
81 template <>
82 std::string ToString(const Rect<int>& value)
83 {
84   std::stringstream ss;
85   ss << value.x << "," << value.y << "," << value.width << "," << value.height;
86   return ss.str();
87 }
88
89
90 std::string PropertyValueToString( const Property::Value& value )
91 {
92   std::string ret;
93
94   switch( value.GetType() )
95   {
96     case Property::NONE:
97     {
98       ret = "NONE";
99       break;
100     }            ///< No type
101     case Property::BOOLEAN:
102     {
103       ret = value.Get<bool>() ? "True" : "False";
104       break;
105     }
106     case Property::FLOAT:
107     {
108
109       ret = ToString( value.Get<float>() );
110       break;
111     }
112     case Property::INTEGER:
113     {
114       ret = ToString( value.Get<int>() );
115       break;
116     }
117     case Property::UNSIGNED_INTEGER:
118     {
119       ret = ToString( value.Get<unsigned int>() );
120       break;
121     }
122     case Property::VECTOR2:
123     {
124       ret = ToString( value.Get<Vector2>() );
125       break;
126     }
127     case Property::VECTOR3:
128     {
129       ret = ToString( value.Get<Vector3>() );
130       break;
131     }
132     case Property::VECTOR4:
133     {
134       ret = ToString( value.Get<Vector4>() );
135       break;
136     }
137     case Property::MATRIX3:
138     {
139       ret = ToString( value.Get<Matrix3>() );
140       break;
141     }
142     case Property::MATRIX:
143     {
144       ret = ToString( value.Get<Matrix>() );
145       break;
146     }
147     case Property::RECTANGLE:
148     {
149       ret = ToString( value.Get< Rect<int> >() );
150       break;
151     }
152     case Property::ROTATION:
153     {
154       break;
155     }
156     case Property::STRING:
157     {
158       ret = value.Get<std::string>();
159       break;
160     }
161     case Property::ARRAY:
162     {
163       ret = std::string("Array Size=") + ToString( value.Get<Property::Array>().size() );
164       break;
165     }
166     case Property::MAP:
167     {
168       ret = std::string("Map Size=") + ToString( value.Get<Property::Map>().size() );
169       break;
170     }
171     case Property::TYPE_COUNT:
172     {
173       ret = "";
174       break;
175     }
176   }
177
178   return ret;
179 }
180
181 /*
182  * Recursively collects all stylesin a node (An array of style names).
183  *
184  * stylesCollection The set of styles from the json file (a json object of named styles)
185  * style The style array to begin the collection from
186  * styleList The style list to add nodes to apply
187  */
188 void CollectAllStyles( const TreeNode& stylesCollection, const TreeNode& style, TreeNodeList& styleList )
189 {
190   // style is an array of style names
191   if( TreeNode::ARRAY == style.GetType() )
192   {
193     for(TreeNode::ConstIterator iter = style.CBegin(); iter != style.CEnd(); ++iter)
194     {
195       if( OptionalString styleName = IsString( (*iter).second ) )
196       {
197         if( OptionalChild node = IsChild( stylesCollection, *styleName) )
198         {
199           styleList.push_back( &(*node) );
200
201           if( OptionalChild subStyle = IsChild( *node, KEYNAME_STYLES ) )
202           {
203             CollectAllStyles( stylesCollection, *subStyle, styleList );
204           }
205         }
206       }
207     }
208   }
209 }
210
211 } // namespace anon
212
213 /*
214  * Sets the handle properties found in the tree node
215  */
216 void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replacement& constant )
217 {
218   if( handle )
219   {
220     for( TreeNode::ConstIterator iter = node.CBegin(); iter != node.CEnd(); ++iter )
221     {
222       const TreeNode::KeyNodePair& keyChild = *iter;
223
224       std::string key( keyChild.first );
225
226       // ignore special fields; type,actors,signals,styles
227       if(key == KEYNAME_TYPE || key == KEYNAME_ACTORS || key == KEYNAME_SIGNALS || key == KEYNAME_STYLES)
228       {
229         continue;
230       }
231
232       // special field 'image' usually contains an json object description
233       // although sometimes refers to a framebuffer
234       if( 0 == keyChild.second.Size() )
235       {
236         if(key == "image")
237         {
238           ImageActor imageActor = ImageActor::DownCast(handle);
239           if(imageActor)
240           {
241             if( OptionalString s = constant.IsString( keyChild.second ) )
242             {
243               FrameBufferImage fb = GetFrameBufferImage(*s, constant);
244               if(fb)
245               {
246                 imageActor.SetImage( fb );
247               }
248             }
249           }
250         }
251       }
252
253       // special field 'effect' references the shader effect instances
254       if(key == "effect")
255       {
256         Actor actor = Actor::DownCast(handle);
257         OptionalString s = constant.IsString( keyChild.second );
258         if(actor && s)
259         {
260           ShaderEffect e = GetShaderEffect(*s, constant);
261           actor.SetShaderEffect(e);
262         }
263         else
264         {
265           DALI_SCRIPT_WARNING("Could not find or set shader effect\n");
266         }
267
268         continue;
269       }
270
271       Handle propertyObject( handle );
272
273       Property::Index index = propertyObject.GetPropertyIndex( key );
274
275       if( Property::INVALID_INDEX == index )
276       {
277         Actor actor = Actor::DownCast(propertyObject);
278         if( actor )
279         {
280           if( ShaderEffect effect = actor.GetShaderEffect() )
281           {
282             index = effect.GetPropertyIndex( key );
283             if(index != Property::INVALID_INDEX)
284             {
285               propertyObject = effect;
286             }
287           }
288         }
289       }
290
291       if( Property::INVALID_INDEX != index )
292       {
293         Property::Type type = propertyObject.GetPropertyType(index);
294
295         Property::Value value;
296         if( !SetPropertyFromNode( keyChild.second, type, value, constant ) )
297         {
298           // verbose as this might not be a problem
299           // eg parent-origin can be a string which is picked up later
300           DALI_SCRIPT_VERBOSE("Could not convert property:%s\n", key.c_str());
301         }
302         else
303         {
304           DALI_SCRIPT_VERBOSE("SetProperty '%s' Index=:%d Value Type=%d Value '%s'\n", key.c_str(), index, value.GetType(), PropertyValueToString(value).c_str() );
305
306           propertyObject.SetProperty( index, value );
307         }
308       }
309       else
310       {
311         DALI_SCRIPT_VERBOSE("SetProperty INVALID '%s' Index=:%d\n", key.c_str(), index);
312       }
313
314     } // for property nodes
315   }
316   else
317   {
318     DALI_SCRIPT_WARNING("Style applied to empty handle\n");
319   }
320 }
321
322 // Set properties from node on handle.
323 void Builder::ApplyProperties( const TreeNode& root, const TreeNode& node,
324                                Dali::Handle& handle, const Replacement& constant )
325 {
326   if( Actor actor = Actor::DownCast(handle) )
327   {
328     SetProperties( node, actor, constant );
329
330     if( actor )
331     {
332       SetupActor( node, actor, constant );
333
334       // add signals
335       SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor );
336
337       SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor );
338    }
339   }
340   else
341   {
342     SetProperties( node, handle, constant );
343   }
344 }
345
346 // Appling by style helper
347 // use FindChildByName() to apply properties referenced in KEYNAME_ACTORS in the node
348 void Builder::ApplyStylesByActor(  const TreeNode& root, const TreeNode& node,
349                                    Dali::Handle& handle, const Replacement& constant )
350 {
351   if( Dali::Actor actor = Dali::Actor::DownCast( handle ) )
352   {
353     if( const TreeNode* actors = node.GetChild( KEYNAME_ACTORS ) )
354     {
355       // in a style the actor subtree properties referenced by actor name
356       for( TreeConstIter iter = actors->CBegin(); iter != actors->CEnd(); ++iter )
357       {
358         Dali::Actor foundActor;
359
360         if( (*iter).first )
361         {
362           foundActor = actor.FindChildByName( (*iter).first );
363         }
364
365         if( !foundActor )
366         {
367           // debug log cannot find searched for actor
368 #if defined(DEBUG_ENABLED)
369           DALI_SCRIPT_VERBOSE("Cannot find actor in style application '%s'\n", (*iter).first);
370 #endif
371         }
372         else
373         {
374 #if defined(DEBUG_ENABLED)
375           DALI_SCRIPT_VERBOSE("Styles applied to actor '%s'\n", (*iter).first);
376 #endif
377           ApplyProperties( root, (*iter).second, foundActor, constant );
378         }
379       }
380     }
381   }
382 }
383
384
385 void Builder::ApplyAllStyleProperties( const TreeNode& root, const TreeNode& node,
386                                        Dali::Handle& handle, const Replacement& constant )
387 {
388   OptionalChild styles = IsChild(root, KEYNAME_STYLES);
389   OptionalChild style  = IsChild(node, KEYNAME_STYLES);
390
391   if( styles && style )
392   {
393     TreeNodeList additionalStyles;
394
395     CollectAllStyles( *styles, *style, additionalStyles );
396
397 #if defined(DEBUG_ENABLED)
398     for(TreeNode::ConstIterator iter = (*style).CBegin(); iter != (*style).CEnd(); ++iter)
399     {
400       if( OptionalString styleName = IsString( (*iter).second ) )
401       {
402         DALI_SCRIPT_VERBOSE("Style Applied '%s'\n", (*styleName).c_str());
403       }
404     }
405 #endif
406
407     // a style may have other styles, which has other styles etc so we apply in reverse by convention.
408     for(TreeNodeList::reverse_iterator iter = additionalStyles.rbegin(); iter != additionalStyles.rend(); ++iter)
409     {
410       ApplyProperties( root, *(*iter), handle, constant );
411
412       ApplyStylesByActor( root, *(*iter), handle, constant );
413     }
414   }
415
416   // applying given node last
417   ApplyProperties( root, node, handle, constant );
418
419   ApplyStylesByActor( root, node, handle, constant );
420
421 }
422
423
424 /*
425  * Create a dali type from a node.
426  * If parent given and an actor type was created then add it to the parent and
427  * recursively add nodes children.
428  */
429 BaseHandle Builder::DoCreate( const TreeNode& root, const TreeNode& node,
430                               Actor parent, const Replacement& replacements )
431 {
432   BaseHandle baseHandle;
433   TypeInfo typeInfo;
434   const TreeNode* templateNode = NULL;
435
436   if( OptionalString typeName = IsString(node, KEYNAME_TYPE) )
437   {
438     typeInfo = TypeRegistry::Get().GetTypeInfo( *typeName );
439
440     if( !typeInfo )
441     {
442       // a template name is also allowed inplace of the type name
443       OptionalChild templates = IsChild( root, KEYNAME_TEMPLATES);
444
445       if( templates )
446       {
447         if( OptionalChild isTemplate = IsChild( *templates, *typeName ) )
448         {
449           templateNode = &(*isTemplate);
450
451           if( OptionalString templateTypeName = IsString(*templateNode, KEYNAME_TYPE) )
452           {
453             typeInfo = TypeRegistry::Get().GetTypeInfo( *templateTypeName );
454           }
455         }
456       }
457     }
458   }
459
460   if(!typeInfo)
461   {
462     DALI_SCRIPT_WARNING("Cannot create Dali type from node '%s'\n", node.GetName());
463   }
464   else
465   {
466     baseHandle       = typeInfo.CreateInstance();
467     Handle handle    = Handle::DownCast(baseHandle);
468     Actor actor      = Actor::DownCast(handle);
469
470     if(handle)
471     {
472
473       DALI_SCRIPT_VERBOSE("Create:%s\n", typeInfo.GetName().c_str());
474
475 #if defined(DEBUG_ENABLED)
476       if(handle)
477       {
478         DALI_SCRIPT_VERBOSE("  Is Handle Object=%d\n", (long*)handle.GetObjectPtr());
479         DALI_SCRIPT_VERBOSE("  Is Handle Property Count=%d\n", handle.GetPropertyCount());
480       }
481
482       if(actor)
483       {
484         DALI_SCRIPT_VERBOSE("  Is Actor id=%d\n", actor.GetId());
485       }
486
487       Toolkit::Control control  = Toolkit::Control::DownCast(handle);
488       if(control)
489       {
490         DALI_SCRIPT_VERBOSE("  Is Control id=%d\n", actor.GetId());
491       }
492 #endif // DEBUG_ENABLED
493
494       if( templateNode )
495       {
496         ApplyProperties( root, *templateNode, handle, replacements );
497
498         if( OptionalChild actors = IsChild( *templateNode, KEYNAME_ACTORS ) )
499         {
500           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
501           {
502             DoCreate( root, (*iter).second, actor, replacements );
503           }
504         }
505       }
506
507       ApplyProperties( root, node, handle, replacements );
508
509       if( actor)
510       {
511         // add children of all the styles
512         if( OptionalChild actors = IsChild( node, KEYNAME_ACTORS ) )
513         {
514           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
515           {
516             DoCreate( root, (*iter).second, actor, replacements );
517           }
518         }
519
520         // apply style on top as they need the children to exist
521         ApplyAllStyleProperties( root, node, actor, replacements );
522
523         // then add to parent
524         if( parent )
525         {
526           parent.Add( actor );
527         }
528       }
529
530     }
531     else
532     {
533       DALI_SCRIPT_WARNING("Cannot create handle from type '%s'\n", typeInfo.GetName().c_str());
534     }
535   }
536
537   return baseHandle;
538 }
539
540 void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replacement& constant )
541 {
542   const Stage& stage = Stage::GetCurrent();
543   Layer root  = stage.GetRootLayer();
544
545   if( OptionalString s = constant.IsString( IsChild(node, "source-actor") ) )
546   {
547     Actor actor = root.FindChildByName(*s);
548     if(actor)
549     {
550       task.SetSourceActor( actor );
551     }
552     else
553     {
554       DALI_SCRIPT_WARNING("Cannot find source actor on stage for render task called '%s'\n", (*s).c_str() );
555     }
556   }
557
558   if( OptionalString s = constant.IsString( IsChild(node, "camera-actor") ) )
559   {
560     CameraActor actor = CameraActor::DownCast( root.FindChildByName(*s) );
561     if(actor)
562     {
563       task.SetCameraActor( actor );
564     }
565     else
566     {
567       DALI_SCRIPT_WARNING("Cannot find camera actor on stage for render task called '%s'\n", (*s).c_str() );
568     }
569   }
570
571   if( OptionalString s = constant.IsString( IsChild(node, "target-frame-buffer") ) )
572   {
573     FrameBufferImage fb = GetFrameBufferImage( *s, constant );
574     if(fb)
575     {
576       task.SetTargetFrameBuffer( fb );
577     }
578     else
579     {
580       DALI_SCRIPT_WARNING("Cannot find target frame buffer '%s'\n", (*s).c_str() );
581     }
582   }
583
584   if( OptionalString s = constant.IsString( IsChild(node, "screen-to-frame-buffer-function") ) )
585   {
586     if("DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION" == *s)
587     {
588       task.SetScreenToFrameBufferFunction( RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION );
589     }
590     else if("FULLSCREEN_FRAMEBUFFER_FUNCTION" == *s)
591     {
592       task.SetScreenToFrameBufferFunction( RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
593     }
594     else
595     {
596       DALI_SCRIPT_WARNING("todo");
597     }
598   }
599
600   // other setup is via the property system
601   SetProperties( node, task, constant ); // @ todo, remove 'source-actor', 'camera-actor'?
602
603 }
604
605 void Builder::CreateRenderTask( const std::string &name )
606 {
607   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
608
609   Replacement constant(mReplacementMap);
610
611   const Stage& stage = Stage::GetCurrent();
612
613   OptionalChild tasks = IsChild(*mParser.GetRoot(), "render-tasks");
614
615   if(tasks)
616   {
617     //
618     // Create the tasks from the current task as generally we want
619     // to setup task zero and onwards. Although this does overwrite
620     // the properties of the current task.
621     //
622     if( OptionalChild renderTask = IsChild(*tasks, name ) )
623     {
624       RenderTaskList list = stage.GetRenderTaskList();
625       unsigned int start = list.GetTaskCount();
626
627       RenderTask task;
628       if(0 == start)
629       {
630         // zero should have already been created by the stage so really
631         // this case should never happen
632         task = list.CreateTask();
633         start++;
634       }
635
636       TreeNode::ConstIterator iter = (*renderTask).CBegin();
637       task = list.GetTask( start - 1 );
638
639       SetupTask( task, (*iter).second, constant  );
640
641       ++iter;
642
643       for(; iter != (*renderTask).CEnd(); ++iter )
644       {
645         task = list.CreateTask();
646         SetupTask( task, (*iter).second, constant );
647       }
648     }
649   }
650 }
651
652 ShaderEffect Builder::GetShaderEffect( const std::string &name)
653 {
654   Replacement constant( mReplacementMap );
655   return GetShaderEffect( name, constant );
656 }
657
658 ShaderEffect Builder::GetShaderEffect( const std::string &name, const Replacement& constant )
659 {
660   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
661
662   ShaderEffect ret;
663
664   ShaderEffectLut::const_iterator iter( mShaderEffectLut.find( name ) );
665   if( iter != mShaderEffectLut.end() )
666   {
667     ret = iter->second;
668   }
669   else
670   {
671     if( OptionalChild effects = IsChild( *mParser.GetRoot(), "shader-effects") )
672     {
673       if( OptionalChild effect = IsChild( *effects, name ) )
674       {
675         Dali::Property::Value propertyMap(Property::MAP);
676         if( SetPropertyFromNode( *effect, Property::MAP, propertyMap, constant ) )
677         {
678           ret = Dali::Scripting::NewShaderEffect( propertyMap );
679           mShaderEffectLut[ name ] = ret;
680         }
681       }
682     }
683   }
684
685   return ret;
686 }
687
688 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name )
689 {
690   Replacement constant( mReplacementMap );
691   return GetFrameBufferImage(name, constant);
692 }
693
694 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Replacement& constant )
695 {
696   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
697
698   FrameBufferImage ret;
699
700   ImageLut::const_iterator iter( mFrameBufferImageLut.find( name ) );
701   if( iter != mFrameBufferImageLut.end() )
702   {
703     ret = iter->second;
704   }
705   else
706   {
707     if( OptionalChild images = IsChild( *mParser.GetRoot(), "frame-buffer-images") )
708     {
709       if( OptionalChild image = IsChild( *images, name ) )
710       {
711         Dali::Property::Value propertyMap(Property::MAP);
712         if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) )
713         {
714           propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage")));
715           ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( propertyMap ) );
716           mFrameBufferImageLut[ name ] = ret;
717         }
718       }
719     }
720   }
721
722   return ret;
723 }
724
725 void Builder::AddActors( Actor toActor )
726 {
727   // 'stage' is the default/by convention section to add from
728   AddActors( "stage", toActor );
729 }
730
731 void Builder::AddActors( const std::string &sectionName, Actor toActor )
732 {
733   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
734
735   PropertyValueMap overrideMap;
736   Replacement replacements(overrideMap, mReplacementMap);
737
738   OptionalChild add = IsChild(*mParser.GetRoot(), sectionName);
739
740   if( add )
741   {
742     for( TreeNode::ConstIterator iter = (*add).CBegin(); iter != (*add).CEnd(); ++iter )
743     {
744       // empty actor adds directly to the stage
745       BaseHandle baseHandle = DoCreate( *mParser.GetRoot(), (*iter).second, Actor(), replacements );
746       Actor actor = Actor::DownCast(baseHandle);
747       if(actor)
748       {
749         toActor.Add( actor );
750       }
751     }
752
753     // if were adding the 'stage' section then also check for a render task called stage
754     // to add automatically
755     if( "stage" == sectionName )
756     {
757       if( OptionalChild renderTasks = IsChild(*mParser.GetRoot(), "render-tasks") )
758       {
759         if( OptionalChild tasks = IsChild(*renderTasks, "stage") )
760         {
761           CreateRenderTask( "stage" );
762         }
763       }
764     }
765   }
766 }
767
768 Animation Builder::CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor )
769 {
770   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
771
772   Animation anim;
773
774   if( OptionalChild animations = IsChild(*mParser.GetRoot(), "animations") )
775   {
776     if( OptionalChild animation = IsChild(*animations, animationName) )
777     {
778       anim = Dali::Toolkit::Internal::CreateAnimation( *animation, replacement, sourceActor );
779     }
780     else
781     {
782       DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed\n", animationName.c_str() );
783     }
784   }
785   else
786   {
787     DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed (no animation section)\n", animationName.c_str() );
788   }
789
790   return anim;
791 }
792
793 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map, Dali::Actor sourceActor )
794 {
795   Replacement replacement(map, mReplacementMap);
796   return CreateAnimation( animationName, replacement, sourceActor);
797 }
798
799 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map )
800 {
801   Replacement replacement(map, mReplacementMap);
802   return CreateAnimation( animationName, replacement, Stage::GetCurrent().GetRootLayer() );
803 }
804
805 Animation Builder::CreateAnimation( const std::string& animationName, Dali::Actor sourceActor )
806 {
807   Replacement replacement( mReplacementMap );
808
809   return CreateAnimation( animationName, replacement, sourceActor );
810 }
811
812 Animation Builder::CreateAnimation( const std::string& animationName )
813 {
814   Replacement replacement( mReplacementMap );
815
816   return CreateAnimation( animationName, replacement, Dali::Stage::GetCurrent().GetRootLayer() );
817 }
818
819 void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::UIFormat format )
820 {
821   DALI_ASSERT_ALWAYS( format == Dali::Toolkit::Builder::JSON && "Currently only JSON is supported" );
822
823   // parser to get constants and includes only
824   Dali::Toolkit::JsonParser parser = Dali::Toolkit::JsonParser::New();
825
826   if( !parser.Parse( data ) )
827   {
828     DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
829                       parser.GetErrorLineNumber(),
830                       parser.GetErrorColumn(),
831                       parser.GetErrorDescription().c_str() );
832
833     DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
834
835   }
836   else
837   {
838     // load constant map (allows the user to override the constants in the json after loading)
839     LoadConstants( *parser.GetRoot(), mReplacementMap );
840
841     // merge includes
842     if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) )
843     {
844       Replacement replacer( mReplacementMap );
845
846       for(TreeNode::ConstIterator iter = (*includes).CBegin(); iter != (*includes).CEnd(); ++iter)
847       {
848         OptionalString filename = replacer.IsString( (*iter).second );
849
850         if( filename )
851         {
852 #if defined(DEBUG_ENABLED)
853           DALI_SCRIPT_VERBOSE("Loading Include '%s'\n", (*filename).c_str());
854 #endif
855           LoadFromString( GetFileContents(*filename) );
856         }
857       }
858     }
859
860     if( !mParser.Parse( data ) )
861     {
862       DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
863                         mParser.GetErrorLineNumber(),
864                         mParser.GetErrorColumn(),
865                         mParser.GetErrorDescription().c_str() );
866
867       DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
868     }
869   }
870
871   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
872
873 }
874
875 void Builder::AddConstants( const PropertyValueMap& map )
876 {
877   for(PropertyValueMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
878   {
879     mReplacementMap[ (*iter).first ] = (*iter).second;
880   }
881 }
882
883 void Builder::AddConstant( const std::string& key, const Property::Value& value )
884 {
885   mReplacementMap[key] = value;
886 }
887
888 const PropertyValueMap& Builder::GetConstants() const
889 {
890   return mReplacementMap;
891 }
892
893 const Property::Value& Builder::GetConstant( const std::string& key ) const
894 {
895   PropertyValueMap::const_iterator iter = mReplacementMap.find( key );
896   if( iter  != mReplacementMap.end() )
897   {
898     return (*iter).second;
899   }
900   else
901   {
902     static Property::Value invalid;
903     return invalid;
904   }
905 }
906
907 void Builder::LoadConstants( const TreeNode& root, PropertyValueMap& intoMap )
908 {
909   Replacement replacer(intoMap);
910
911   if( OptionalChild constants = IsChild(root, "constants") )
912   {
913     for(TreeNode::ConstIterator iter = (*constants).CBegin();
914         iter != (*constants).CEnd(); ++iter)
915     {
916       Dali::Property::Value property;
917       if( (*iter).second.GetName() )
918       {
919 #if defined(DEBUG_ENABLED)
920         DALI_SCRIPT_VERBOSE("Constant set from json '%s'\n", (*iter).second.GetName());
921 #endif
922         if( SetPropertyFromNode( (*iter).second, property, replacer ) )
923         {
924           intoMap[ (*iter).second.GetName() ] = property;
925         }
926         else
927         {
928           DALI_SCRIPT_WARNING("Cannot convert property for constant %s\n",
929                               (*iter).second.GetName() == NULL ? "no name?" : (*iter).second.GetName());
930         }
931       }
932     }
933   }
934
935 #if defined(DEBUG_ENABLED)
936   PropertyValueMap::const_iterator iter = intoMap.find( "CONFIG_SCRIPT_LOG_LEVEL" );
937   if( iter != intoMap.end() && (*iter).second.GetType() == Property::STRING )
938   {
939     std::string logLevel( (*iter).second.Get< std::string >() );
940     if( logLevel == "NoLogging" )
941     {
942       gFilterScript->SetLogLevel( Integration::Log::NoLogging );
943     }
944     else if( logLevel == "Concise" )
945     {
946       gFilterScript->SetLogLevel( Integration::Log::Concise );
947     }
948     else if( logLevel == "General" )
949     {
950       gFilterScript->SetLogLevel( Integration::Log::General );
951     }
952     else if( logLevel == "Verbose" )
953     {
954       gFilterScript->SetLogLevel( Integration::Log::Verbose );
955     }
956   }
957 #endif
958
959 }
960
961 bool Builder::ApplyStyle( const std::string& styleName, Handle& handle )
962 {
963   Replacement replacer( mReplacementMap );
964   return ApplyStyle( styleName, handle, replacer );
965 }
966
967 bool Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement )
968 {
969   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
970
971   OptionalChild styles = IsChild( *mParser.GetRoot(), KEYNAME_STYLES );
972   OptionalChild style  = IsChild( *styles, styleName );
973
974   if( styles && style )
975   {
976     ApplyAllStyleProperties( *mParser.GetRoot(), *style, handle, replacement );
977     return true;
978   }
979   else
980   {
981     DALI_SCRIPT_WARNING("No styles section to create style '%s'\n", styleName.c_str());
982     return false;
983   }
984 }
985
986 BaseHandle Builder::Create( const std::string& templateName, const PropertyValueMap& map )
987 {
988   Replacement replacement( map, mReplacementMap );
989   return Create( templateName, replacement );
990 }
991
992 BaseHandle Builder::Create( const std::string& templateName, const Replacement& constant )
993 {
994   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
995
996   BaseHandle baseHandle;
997
998   OptionalChild templates = IsChild(*mParser.GetRoot(), KEYNAME_TEMPLATES);
999
1000   if( !templates )
1001   {
1002     DALI_SCRIPT_WARNING("No template section found to CreateFromTemplate\n");
1003   }
1004   else
1005   {
1006     OptionalChild childTemplate = IsChild(*templates, templateName);
1007     if(!childTemplate)
1008     {
1009       DALI_SCRIPT_WARNING("Template '%s' does not exist in template section\n", templateName.c_str());
1010     }
1011     else
1012     {
1013       OptionalString type = constant.IsString( IsChild(*childTemplate, KEYNAME_TYPE) );
1014
1015       if(!type)
1016       {
1017         DALI_SCRIPT_WARNING("Cannot create template '%s' as template section is missing 'type'\n", templateName.c_str());
1018       }
1019       else
1020       {
1021         baseHandle = DoCreate( *mParser.GetRoot(), *childTemplate, Actor(), constant );
1022       }
1023     }
1024   }
1025
1026   return baseHandle;
1027 }
1028
1029
1030 BaseHandle Builder::Create( const std::string& templateName )
1031 {
1032   Replacement replacement( mReplacementMap );
1033   return Create( templateName, replacement );
1034 }
1035
1036 Builder::Builder()
1037 : mSlotDelegate( this )
1038 {
1039   mParser = Dali::Toolkit::JsonParser::New();
1040 }
1041
1042 Builder::~Builder()
1043 {
1044 }
1045
1046 } // namespace Internal
1047
1048 } // namespace Toolkit
1049
1050 } // namespace Dali