License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-toolkit.git] / optional / 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
24 // INTERNAL INCLUDES
25 #include <dali/dali.h>
26 #include <dali/integration-api/debug.h>
27
28 #include <dali-toolkit/public-api/controls/control.h>
29 #include <dali-toolkit/public-api/builder/json-parser.h>
30
31 #include <dali-toolkit/internal/builder/builder-get-is.inl.h>
32 #include <dali-toolkit/internal/builder/builder-filesystem.h>
33 #include <dali-toolkit/internal/builder/builder-declarations.h>
34 #include <dali-toolkit/internal/builder/replacement.h>
35
36 namespace Dali
37 {
38
39 namespace Toolkit
40 {
41
42 namespace Internal
43 {
44 class Replacement;
45
46 extern Animation CreateAnimation(const TreeNode& child, const Replacement& replacements, const Dali::Actor searchRoot );
47 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value );
48 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value, const Replacement& replacements );
49 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value );
50 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value, const Replacement& replacements );
51 extern Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor);
52 extern Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor);
53 extern Actor SetupActor( const TreeNode& node, Actor& actor );
54 extern Control SetupControl( const TreeNode& node, Control& actor );
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
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 );
333
334       Control control  = Control::DownCast(actor);
335
336       if( control )
337       {
338         SetupControl( node, control );
339       }
340
341       // add signals
342       SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor );
343
344       SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor );
345    }
346   }
347   else
348   {
349     SetProperties( node, handle, constant );
350   }
351 }
352
353 // Appling by style helper
354 // use FindChildByName() to apply properties referenced in KEYNAME_ACTORS in the node
355 void Builder::ApplyStylesByActor(  const TreeNode& root, const TreeNode& node,
356                                    Dali::Handle& handle, const Replacement& constant )
357 {
358   if( Dali::Actor actor = Dali::Actor::DownCast( handle ) )
359   {
360     if( const TreeNode* actors = node.GetChild( KEYNAME_ACTORS ) )
361     {
362       // in a style the actor subtree properties referenced by actor name
363       for( TreeConstIter iter = actors->CBegin(); iter != actors->CEnd(); ++iter )
364       {
365         Dali::Actor foundActor;
366
367         if( (*iter).first )
368         {
369           foundActor = actor.FindChildByName( (*iter).first );
370         }
371
372         if( !foundActor )
373         {
374           // debug log cannot find searched for actor
375 #if defined(DEBUG_ENABLED)
376           DALI_SCRIPT_VERBOSE("Cannot find actor in style application '%s'\n", (*iter).first);
377 #endif
378         }
379         else
380         {
381 #if defined(DEBUG_ENABLED)
382           DALI_SCRIPT_VERBOSE("Styles applied to actor '%s'\n", (*iter).first);
383 #endif
384           ApplyProperties( root, (*iter).second, foundActor, constant );
385         }
386       }
387     }
388   }
389 }
390
391
392 void Builder::ApplyAllStyleProperties( const TreeNode& root, const TreeNode& node,
393                                        Dali::Handle& handle, const Replacement& constant )
394 {
395   OptionalChild styles = IsChild(root, KEYNAME_STYLES);
396   OptionalChild style  = IsChild(node, KEYNAME_STYLES);
397
398   if( styles && style )
399   {
400     TreeNodeList additionalStyles;
401
402     CollectAllStyles( *styles, *style, additionalStyles );
403
404 #if defined(DEBUG_ENABLED)
405     for(TreeNode::ConstIterator iter = (*style).CBegin(); iter != (*style).CEnd(); ++iter)
406     {
407       if( OptionalString styleName = IsString( (*iter).second ) )
408       {
409         DALI_SCRIPT_VERBOSE("Style Applied '%s'\n", (*styleName).c_str());
410       }
411     }
412 #endif
413
414     // a style may have other styles, which has other styles etc so we apply in reverse by convention.
415     for(TreeNodeList::reverse_iterator iter = additionalStyles.rbegin(); iter != additionalStyles.rend(); ++iter)
416     {
417       ApplyProperties( root, *(*iter), handle, constant );
418
419       ApplyStylesByActor( root, *(*iter), handle, constant );
420     }
421   }
422
423   // applying given node last
424   ApplyProperties( root, node, handle, constant );
425
426   ApplyStylesByActor( root, node, handle, constant );
427
428 }
429
430
431 /*
432  * Create a dali type from a node.
433  * If parent given and an actor type was created then add it to the parent and
434  * recursively add nodes children.
435  */
436 BaseHandle Builder::DoCreate( const TreeNode& root, const TreeNode& node,
437                               Actor parent, const Replacement& replacements )
438 {
439   BaseHandle baseHandle;
440   TypeInfo typeInfo;
441   const TreeNode* templateNode = NULL;
442
443   if( OptionalString typeName = IsString(node, KEYNAME_TYPE) )
444   {
445     typeInfo = TypeRegistry::Get().GetTypeInfo( *typeName );
446
447     if( !typeInfo )
448     {
449       // a template name is also allowed inplace of the type name
450       OptionalChild templates = IsChild( root, KEYNAME_TEMPLATES);
451
452       if( templates )
453       {
454         if( OptionalChild isTemplate = IsChild( *templates, *typeName ) )
455         {
456           templateNode = &(*isTemplate);
457
458           if( OptionalString templateTypeName = IsString(*templateNode, KEYNAME_TYPE) )
459           {
460             typeInfo = TypeRegistry::Get().GetTypeInfo( *templateTypeName );
461           }
462         }
463       }
464     }
465   }
466
467   if(!typeInfo)
468   {
469     DALI_SCRIPT_WARNING("Cannot create Dali type from node '%s'\n", node.GetName());
470   }
471   else
472   {
473     baseHandle       = typeInfo.CreateInstance();
474     Handle handle    = Handle::DownCast(baseHandle);
475     Actor actor      = Actor::DownCast(handle);
476     Control control  = Control::DownCast(handle);
477
478     if(handle)
479     {
480
481       DALI_SCRIPT_VERBOSE("Create:%s\n", typeInfo.GetName().c_str());
482
483 #if defined(DEBUG_ENABLED)
484       if(handle)
485       {
486         DALI_SCRIPT_VERBOSE("  Is Handle Object=%d\n", (long*)handle.GetObjectPtr());
487         DALI_SCRIPT_VERBOSE("  Is Handle Property Count=%d\n", handle.GetPropertyCount());
488       }
489
490       if(actor)
491       {
492         DALI_SCRIPT_VERBOSE("  Is Actor id=%d\n", actor.GetId());
493       }
494
495       if(control)
496       {
497         DALI_SCRIPT_VERBOSE("  Is Control id=%d\n", actor.GetId());
498       }
499 #endif // DEBUG_ENABLED
500
501       if( templateNode )
502       {
503         ApplyProperties( root, *templateNode, handle, replacements );
504
505         if( OptionalChild actors = IsChild( *templateNode, KEYNAME_ACTORS ) )
506         {
507           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
508           {
509             DoCreate( root, (*iter).second, actor, replacements );
510           }
511         }
512       }
513
514       ApplyProperties( root, node, handle, replacements );
515
516       if( actor)
517       {
518         // add children of all the styles
519         if( OptionalChild actors = IsChild( node, KEYNAME_ACTORS ) )
520         {
521           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
522           {
523             DoCreate( root, (*iter).second, actor, replacements );
524           }
525         }
526
527         // apply style on top as they need the children to exist
528         ApplyAllStyleProperties( root, node, actor, replacements );
529
530         // then add to parent
531         if( parent )
532         {
533           parent.Add( actor );
534         }
535       }
536
537     }
538     else
539     {
540       DALI_SCRIPT_WARNING("Cannot create handle from type '%s'\n", typeInfo.GetName().c_str());
541     }
542   }
543
544   return baseHandle;
545 }
546
547
548 ActorContainer Builder::GetTopLevelActors() const
549 {
550   // deprecated function.
551   return ActorContainer();
552 }
553
554 Animation Builder::GetAnimation( const std::string &name ) const
555 {
556   // deprecated
557   return Animation();
558 }
559
560 void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replacement& constant )
561 {
562   const Stage& stage = Stage::GetCurrent();
563   Layer root  = stage.GetRootLayer();
564
565   if( OptionalString s = constant.IsString( IsChild(node, "source-actor") ) )
566   {
567     Actor actor = root.FindChildByName(*s);
568     if(actor)
569     {
570       task.SetSourceActor( actor );
571     }
572     else
573     {
574       DALI_SCRIPT_WARNING("Cannot find source actor on stage for render task called '%s'\n", (*s).c_str() );
575     }
576   }
577
578   if( OptionalString s = constant.IsString( IsChild(node, "camera-actor") ) )
579   {
580     CameraActor actor = CameraActor::DownCast( root.FindChildByName(*s) );
581     if(actor)
582     {
583       task.SetCameraActor( actor );
584     }
585     else
586     {
587       DALI_SCRIPT_WARNING("Cannot find camera actor on stage for render task called '%s'\n", (*s).c_str() );
588     }
589   }
590
591   if( OptionalString s = constant.IsString( IsChild(node, "target-frame-buffer") ) )
592   {
593     FrameBufferImage fb = GetFrameBufferImage( *s, constant );
594     if(fb)
595     {
596       task.SetTargetFrameBuffer( fb );
597     }
598     else
599     {
600       DALI_SCRIPT_WARNING("Cannot find target frame buffer '%s'\n", (*s).c_str() );
601     }
602   }
603
604   if( OptionalString s = constant.IsString( IsChild(node, "screen-to-frame-buffer-function") ) )
605   {
606     if("DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION" == *s)
607     {
608       task.SetScreenToFrameBufferFunction( RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION );
609     }
610     else if("FULLSCREEN_FRAMEBUFFER_FUNCTION" == *s)
611     {
612       task.SetScreenToFrameBufferFunction( RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
613     }
614     else
615     {
616       DALI_SCRIPT_WARNING("todo");
617     }
618   }
619
620   // other setup is via the property system
621   SetProperties( node, task, constant ); // @ todo, remove 'source-actor', 'camera-actor'?
622
623 }
624
625 void Builder::CreateRenderTask( const std::string &name )
626 {
627   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
628
629   Replacement constant(mReplacementMap);
630
631   const Stage& stage = Stage::GetCurrent();
632
633   OptionalChild tasks = IsChild(*mParser.GetRoot(), "render-tasks");
634
635   if(tasks)
636   {
637     //
638     // Create the tasks from the current task as generally we want
639     // to setup task zero and onwards. Although this does overwrite
640     // the properties of the current task.
641     //
642     if( OptionalChild renderTask = IsChild(*tasks, name ) )
643     {
644       RenderTaskList list = stage.GetRenderTaskList();
645       unsigned int start = list.GetTaskCount();
646
647       RenderTask task;
648       if(0 == start)
649       {
650         // zero should have already been created by the stage so really
651         // this case should never happen
652         task = list.CreateTask();
653         start++;
654       }
655
656       TreeNode::ConstIterator iter = (*renderTask).CBegin();
657       task = list.GetTask( start - 1 );
658
659       SetupTask( task, (*iter).second, constant  );
660
661       ++iter;
662
663       for(; iter != (*renderTask).CEnd(); ++iter )
664       {
665         task = list.CreateTask();
666         SetupTask( task, (*iter).second, constant );
667       }
668     }
669   }
670 }
671
672 ShaderEffect Builder::GetShaderEffect( const std::string &name)
673 {
674   Replacement constant( mReplacementMap );
675   return GetShaderEffect( name, constant );
676 }
677
678 ShaderEffect Builder::GetShaderEffect( const std::string &name, const Replacement& constant )
679 {
680   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
681
682   ShaderEffect ret;
683
684   ShaderEffectLut::const_iterator iter( mShaderEffectLut.find( name ) );
685   if( iter != mShaderEffectLut.end() )
686   {
687     ret = iter->second;
688   }
689   else
690   {
691     if( OptionalChild effects = IsChild( *mParser.GetRoot(), "shader-effects") )
692     {
693       if( OptionalChild effect = IsChild( *effects, name ) )
694       {
695         Dali::Property::Value propertyMap(Property::MAP);
696         if( SetPropertyFromNode( *effect, Property::MAP, propertyMap, constant ) )
697         {
698           ret = Dali::Scripting::NewShaderEffect( propertyMap );
699           mShaderEffectLut[ name ] = ret;
700         }
701       }
702     }
703   }
704
705   return ret;
706 }
707
708 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name )
709 {
710   Replacement constant( mReplacementMap );
711   return GetFrameBufferImage(name, constant);
712 }
713
714 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Replacement& constant )
715 {
716   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
717
718   FrameBufferImage ret;
719
720   ImageLut::const_iterator iter( mFrameBufferImageLut.find( name ) );
721   if( iter != mFrameBufferImageLut.end() )
722   {
723     ret = iter->second;
724   }
725   else
726   {
727     if( OptionalChild images = IsChild( *mParser.GetRoot(), "frame-buffer-images") )
728     {
729       if( OptionalChild image = IsChild( *images, name ) )
730       {
731         Dali::Property::Value propertyMap(Property::MAP);
732         if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) )
733         {
734           propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage")));
735           ret = Dali::Scripting::NewImage( propertyMap );
736           mFrameBufferImageLut[ name ] = ret;
737         }
738       }
739     }
740   }
741
742   return ret;
743 }
744
745 Font Builder::GetFont( const std::string& name ) const
746 {
747   // deprecated function.
748   Font font;
749   return font;
750 }
751
752 TextStyle Builder::GetTextStyle( const std::string& name ) const
753 {
754   // deprecated
755   return TextStyle();
756 }
757
758 Image Builder::GetImage( const std::string& name) const
759 {
760   // deprecated function.
761   return Image();
762 }
763
764 Actor Builder::GetActor( const std::string &name ) const
765 {
766   // deprecated function.
767   return Actor();
768 }
769
770 void Builder::AddActors( Actor toActor )
771 {
772   // 'stage' is the default/by convention section to add from
773   AddActors( "stage", toActor );
774 }
775
776 void Builder::AddActors( const std::string &sectionName, Actor toActor )
777 {
778   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
779
780   PropertyValueMap overrideMap;
781   Replacement replacements(overrideMap, mReplacementMap);
782
783   OptionalChild add = IsChild(*mParser.GetRoot(), sectionName);
784
785   if( add )
786   {
787     for( TreeNode::ConstIterator iter = (*add).CBegin(); iter != (*add).CEnd(); ++iter )
788     {
789       // empty actor adds directly to the stage
790       BaseHandle baseHandle = DoCreate( *mParser.GetRoot(), (*iter).second, Actor(), replacements );
791       Actor actor = Actor::DownCast(baseHandle);
792       if(actor)
793       {
794         toActor.Add( actor );
795       }
796     }
797
798     // if were adding the 'stage' section then also check for a render task called stage
799     // to add automatically
800     if( "stage" == sectionName )
801     {
802       if( OptionalChild renderTasks = IsChild(*mParser.GetRoot(), "render-tasks") )
803       {
804         if( OptionalChild tasks = IsChild(*renderTasks, "stage") )
805         {
806           CreateRenderTask( "stage" );
807         }
808       }
809     }
810   }
811 }
812
813 Animation Builder::CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor )
814 {
815   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
816
817   Animation anim;
818
819   if( OptionalChild animations = IsChild(*mParser.GetRoot(), "animations") )
820   {
821     if( OptionalChild animation = IsChild(*animations, animationName) )
822     {
823       anim = Dali::Toolkit::Internal::CreateAnimation( *animation, replacement, sourceActor );
824     }
825     else
826     {
827       DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed\n", animationName.c_str() );
828     }
829   }
830   else
831   {
832     DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed (no animation section)\n", animationName.c_str() );
833   }
834
835   return anim;
836 }
837
838 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map, Dali::Actor sourceActor )
839 {
840   Replacement replacement(map, mReplacementMap);
841   return CreateAnimation( animationName, replacement, sourceActor);
842 }
843
844 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map )
845 {
846   Replacement replacement(map, mReplacementMap);
847   return CreateAnimation( animationName, replacement, Stage::GetCurrent().GetRootLayer() );
848 }
849
850 Animation Builder::CreateAnimation( const std::string& animationName, Dali::Actor sourceActor )
851 {
852   Replacement replacement( mReplacementMap );
853
854   return CreateAnimation( animationName, replacement, sourceActor );
855 }
856
857 Animation Builder::CreateAnimation( const std::string& animationName )
858 {
859   Replacement replacement( mReplacementMap );
860
861   return CreateAnimation( animationName, replacement, Dali::Stage::GetCurrent().GetRootLayer() );
862 }
863
864 void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::UIFormat format )
865 {
866   DALI_ASSERT_ALWAYS( format == Dali::Toolkit::Builder::JSON && "Currently only JSON is supported" );
867
868   // parser to get constants and includes only
869   Dali::Toolkit::JsonParser parser = Dali::Toolkit::JsonParser::New();
870
871   if( !parser.Parse( data ) )
872   {
873     DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
874                       parser.GetErrorLineNumber(),
875                       parser.GetErrorColumn(),
876                       parser.GetErrorDescription().c_str() );
877
878     DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
879
880   }
881   else
882   {
883     // load constant map (allows the user to override the constants in the json after loading)
884     LoadConstants( *parser.GetRoot(), mReplacementMap );
885
886     // merge includes
887     if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) )
888     {
889       Replacement replacer( mReplacementMap );
890
891       for(TreeNode::ConstIterator iter = (*includes).CBegin(); iter != (*includes).CEnd(); ++iter)
892       {
893         OptionalString filename = replacer.IsString( (*iter).second );
894
895         if( filename )
896         {
897 #if defined(DEBUG_ENABLED)
898           DALI_SCRIPT_VERBOSE("Loading Include '%s'\n", (*filename).c_str());
899 #endif
900           LoadFromString( GetFileContents(*filename) );
901         }
902       }
903     }
904
905     if( !mParser.Parse( data ) )
906     {
907       DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
908                         mParser.GetErrorLineNumber(),
909                         mParser.GetErrorColumn(),
910                         mParser.GetErrorDescription().c_str() );
911
912       DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
913     }
914   }
915
916   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
917
918 }
919
920 void Builder::AddConstants( const PropertyValueMap& map )
921 {
922   for(PropertyValueMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
923   {
924     mReplacementMap[ (*iter).first ] = (*iter).second;
925   }
926 }
927
928 void Builder::AddConstant( const std::string& key, const Property::Value& value )
929 {
930   mReplacementMap[key] = value;
931 }
932
933 const PropertyValueMap& Builder::GetConstants() const
934 {
935   return mReplacementMap;
936 }
937
938 const Property::Value& Builder::GetConstant( const std::string& key ) const
939 {
940   PropertyValueMap::const_iterator iter = mReplacementMap.find( key );
941   if( iter  != mReplacementMap.end() )
942   {
943     return (*iter).second;
944   }
945   else
946   {
947     static Property::Value invalid;
948     return invalid;
949   }
950 }
951
952 void Builder::LoadConstants( const TreeNode& root, PropertyValueMap& intoMap )
953 {
954   Replacement replacer(intoMap);
955
956   if( OptionalChild constants = IsChild(root, "constants") )
957   {
958     for(TreeNode::ConstIterator iter = (*constants).CBegin();
959         iter != (*constants).CEnd(); ++iter)
960     {
961       Dali::Property::Value property;
962       if( (*iter).second.GetName() )
963       {
964 #if defined(DEBUG_ENABLED)
965         DALI_SCRIPT_VERBOSE("Constant set from json '%s'\n", (*iter).second.GetName());
966 #endif
967         if( SetPropertyFromNode( (*iter).second, property, replacer ) )
968         {
969           intoMap[ (*iter).second.GetName() ] = property;
970         }
971         else
972         {
973           DALI_SCRIPT_WARNING("Cannot convert property for constant %s\n",
974                               (*iter).second.GetName() == NULL ? "no name?" : (*iter).second.GetName());
975         }
976       }
977     }
978   }
979
980 #if defined(DEBUG_ENABLED)
981   PropertyValueMap::const_iterator iter = intoMap.find( "CONFIG_SCRIPT_LOG_LEVEL" );
982   if( iter != intoMap.end() && (*iter).second.GetType() == Property::STRING )
983   {
984     std::string logLevel( (*iter).second.Get< std::string >() );
985     if( logLevel == "NoLogging" )
986     {
987       gFilterScript->SetLogLevel( Integration::Log::NoLogging );
988     }
989     else if( logLevel == "Concise" )
990     {
991       gFilterScript->SetLogLevel( Integration::Log::Concise );
992     }
993     else if( logLevel == "General" )
994     {
995       gFilterScript->SetLogLevel( Integration::Log::General );
996     }
997     else if( logLevel == "Verbose" )
998     {
999       gFilterScript->SetLogLevel( Integration::Log::Verbose );
1000     }
1001   }
1002 #endif
1003
1004 }
1005
1006 void Builder::ApplyStyle( const std::string& styleName, Handle& handle )
1007 {
1008   Replacement replacer( mReplacementMap );
1009   ApplyStyle( styleName, handle, replacer );
1010 }
1011
1012 void Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement )
1013 {
1014   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1015
1016   OptionalChild styles = IsChild( *mParser.GetRoot(), KEYNAME_STYLES );
1017   OptionalChild style  = IsChild( *styles, styleName );
1018
1019   if( styles && style )
1020   {
1021     ApplyAllStyleProperties( *mParser.GetRoot(), *style, handle, replacement );
1022   }
1023   else
1024   {
1025     DALI_SCRIPT_WARNING("No styles section to create style '%s'\n", styleName.c_str());
1026   }
1027
1028 }
1029
1030 BaseHandle Builder::Create( const std::string& templateName, const PropertyValueMap& map )
1031 {
1032   Replacement replacement( map, mReplacementMap );
1033   return Create( templateName, replacement );
1034 }
1035
1036 BaseHandle Builder::Create( const std::string& templateName, const Replacement& constant )
1037 {
1038   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1039
1040   BaseHandle baseHandle;
1041
1042   OptionalChild templates = IsChild(*mParser.GetRoot(), KEYNAME_TEMPLATES);
1043
1044   if( !templates )
1045   {
1046     DALI_SCRIPT_WARNING("No template section found to CreateFromTemplate\n");
1047   }
1048   else
1049   {
1050     OptionalChild childTemplate = IsChild(*templates, templateName);
1051     if(!childTemplate)
1052     {
1053       DALI_SCRIPT_WARNING("Template '%s' does not exist in template section\n", templateName.c_str());
1054     }
1055     else
1056     {
1057       OptionalString type = constant.IsString( IsChild(*childTemplate, KEYNAME_TYPE) );
1058
1059       if(!type)
1060       {
1061         DALI_SCRIPT_WARNING("Cannot create template '%s' as template section is missing 'type'\n", templateName.c_str());
1062       }
1063       else
1064       {
1065         baseHandle = DoCreate( *mParser.GetRoot(), *childTemplate, Actor(), constant );
1066       }
1067     }
1068   }
1069
1070   return baseHandle;
1071 }
1072
1073
1074 BaseHandle Builder::Create( const std::string& templateName )
1075 {
1076   Replacement replacement( mReplacementMap );
1077   return Create( templateName, replacement );
1078 }
1079
1080 Builder::Builder()
1081 : mSlotDelegate( this )
1082 {
1083   mParser = Dali::Toolkit::JsonParser::New();
1084 }
1085
1086 Builder::~Builder()
1087 {
1088 }
1089
1090 } // namespace Internal
1091
1092 } // namespace Toolkit
1093
1094 } // namespace Dali