Conversion to Apache 2.0 license
[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 );
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       // 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
541 ActorContainer Builder::GetTopLevelActors() const
542 {
543   // deprecated function.
544   return ActorContainer();
545 }
546
547 Animation Builder::GetAnimation( const std::string &name ) const
548 {
549   // deprecated
550   return Animation();
551 }
552
553 void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replacement& constant )
554 {
555   const Stage& stage = Stage::GetCurrent();
556   Layer root  = stage.GetRootLayer();
557
558   if( OptionalString s = constant.IsString( IsChild(node, "source-actor") ) )
559   {
560     Actor actor = root.FindChildByName(*s);
561     if(actor)
562     {
563       task.SetSourceActor( actor );
564     }
565     else
566     {
567       DALI_SCRIPT_WARNING("Cannot find source actor on stage for render task called '%s'\n", (*s).c_str() );
568     }
569   }
570
571   if( OptionalString s = constant.IsString( IsChild(node, "camera-actor") ) )
572   {
573     CameraActor actor = CameraActor::DownCast( root.FindChildByName(*s) );
574     if(actor)
575     {
576       task.SetCameraActor( actor );
577     }
578     else
579     {
580       DALI_SCRIPT_WARNING("Cannot find camera actor on stage for render task called '%s'\n", (*s).c_str() );
581     }
582   }
583
584   if( OptionalString s = constant.IsString( IsChild(node, "target-frame-buffer") ) )
585   {
586     FrameBufferImage fb = GetFrameBufferImage( *s, constant );
587     if(fb)
588     {
589       task.SetTargetFrameBuffer( fb );
590     }
591     else
592     {
593       DALI_SCRIPT_WARNING("Cannot find target frame buffer '%s'\n", (*s).c_str() );
594     }
595   }
596
597   if( OptionalString s = constant.IsString( IsChild(node, "screen-to-frame-buffer-function") ) )
598   {
599     if("DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION" == *s)
600     {
601       task.SetScreenToFrameBufferFunction( RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION );
602     }
603     else if("FULLSCREEN_FRAMEBUFFER_FUNCTION" == *s)
604     {
605       task.SetScreenToFrameBufferFunction( RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
606     }
607     else
608     {
609       DALI_SCRIPT_WARNING("todo");
610     }
611   }
612
613   // other setup is via the property system
614   SetProperties( node, task, constant ); // @ todo, remove 'source-actor', 'camera-actor'?
615
616 }
617
618 void Builder::CreateRenderTask( const std::string &name )
619 {
620   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
621
622   Replacement constant(mReplacementMap);
623
624   const Stage& stage = Stage::GetCurrent();
625
626   OptionalChild tasks = IsChild(*mParser.GetRoot(), "render-tasks");
627
628   if(tasks)
629   {
630     //
631     // Create the tasks from the current task as generally we want
632     // to setup task zero and onwards. Although this does overwrite
633     // the properties of the current task.
634     //
635     if( OptionalChild renderTask = IsChild(*tasks, name ) )
636     {
637       RenderTaskList list = stage.GetRenderTaskList();
638       unsigned int start = list.GetTaskCount();
639
640       RenderTask task;
641       if(0 == start)
642       {
643         // zero should have already been created by the stage so really
644         // this case should never happen
645         task = list.CreateTask();
646         start++;
647       }
648
649       TreeNode::ConstIterator iter = (*renderTask).CBegin();
650       task = list.GetTask( start - 1 );
651
652       SetupTask( task, (*iter).second, constant  );
653
654       ++iter;
655
656       for(; iter != (*renderTask).CEnd(); ++iter )
657       {
658         task = list.CreateTask();
659         SetupTask( task, (*iter).second, constant );
660       }
661     }
662   }
663 }
664
665 ShaderEffect Builder::GetShaderEffect( const std::string &name)
666 {
667   Replacement constant( mReplacementMap );
668   return GetShaderEffect( name, constant );
669 }
670
671 ShaderEffect Builder::GetShaderEffect( const std::string &name, const Replacement& constant )
672 {
673   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
674
675   ShaderEffect ret;
676
677   ShaderEffectLut::const_iterator iter( mShaderEffectLut.find( name ) );
678   if( iter != mShaderEffectLut.end() )
679   {
680     ret = iter->second;
681   }
682   else
683   {
684     if( OptionalChild effects = IsChild( *mParser.GetRoot(), "shader-effects") )
685     {
686       if( OptionalChild effect = IsChild( *effects, name ) )
687       {
688         Dali::Property::Value propertyMap(Property::MAP);
689         if( SetPropertyFromNode( *effect, Property::MAP, propertyMap, constant ) )
690         {
691           ret = Dali::Scripting::NewShaderEffect( propertyMap );
692           mShaderEffectLut[ name ] = ret;
693         }
694       }
695     }
696   }
697
698   return ret;
699 }
700
701 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name )
702 {
703   Replacement constant( mReplacementMap );
704   return GetFrameBufferImage(name, constant);
705 }
706
707 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Replacement& constant )
708 {
709   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
710
711   FrameBufferImage ret;
712
713   ImageLut::const_iterator iter( mFrameBufferImageLut.find( name ) );
714   if( iter != mFrameBufferImageLut.end() )
715   {
716     ret = iter->second;
717   }
718   else
719   {
720     if( OptionalChild images = IsChild( *mParser.GetRoot(), "frame-buffer-images") )
721     {
722       if( OptionalChild image = IsChild( *images, name ) )
723       {
724         Dali::Property::Value propertyMap(Property::MAP);
725         if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) )
726         {
727           propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage")));
728           ret = Dali::Scripting::NewImage( propertyMap );
729           mFrameBufferImageLut[ name ] = ret;
730         }
731       }
732     }
733   }
734
735   return ret;
736 }
737
738 Font Builder::GetFont( const std::string& name ) const
739 {
740   // deprecated function.
741   Font font;
742   return font;
743 }
744
745 TextStyle Builder::GetTextStyle( const std::string& name ) const
746 {
747   // deprecated
748   return TextStyle();
749 }
750
751 Image Builder::GetImage( const std::string& name) const
752 {
753   // deprecated function.
754   return Image();
755 }
756
757 Actor Builder::GetActor( const std::string &name ) const
758 {
759   // deprecated function.
760   return Actor();
761 }
762
763 void Builder::AddActors( Actor toActor )
764 {
765   // 'stage' is the default/by convention section to add from
766   AddActors( "stage", toActor );
767 }
768
769 void Builder::AddActors( const std::string &sectionName, Actor toActor )
770 {
771   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
772
773   PropertyValueMap overrideMap;
774   Replacement replacements(overrideMap, mReplacementMap);
775
776   OptionalChild add = IsChild(*mParser.GetRoot(), sectionName);
777
778   if( add )
779   {
780     for( TreeNode::ConstIterator iter = (*add).CBegin(); iter != (*add).CEnd(); ++iter )
781     {
782       // empty actor adds directly to the stage
783       BaseHandle baseHandle = DoCreate( *mParser.GetRoot(), (*iter).second, Actor(), replacements );
784       Actor actor = Actor::DownCast(baseHandle);
785       if(actor)
786       {
787         toActor.Add( actor );
788       }
789     }
790
791     // if were adding the 'stage' section then also check for a render task called stage
792     // to add automatically
793     if( "stage" == sectionName )
794     {
795       if( OptionalChild renderTasks = IsChild(*mParser.GetRoot(), "render-tasks") )
796       {
797         if( OptionalChild tasks = IsChild(*renderTasks, "stage") )
798         {
799           CreateRenderTask( "stage" );
800         }
801       }
802     }
803   }
804 }
805
806 Animation Builder::CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor )
807 {
808   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
809
810   Animation anim;
811
812   if( OptionalChild animations = IsChild(*mParser.GetRoot(), "animations") )
813   {
814     if( OptionalChild animation = IsChild(*animations, animationName) )
815     {
816       anim = Dali::Toolkit::Internal::CreateAnimation( *animation, replacement, sourceActor );
817     }
818     else
819     {
820       DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed\n", animationName.c_str() );
821     }
822   }
823   else
824   {
825     DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed (no animation section)\n", animationName.c_str() );
826   }
827
828   return anim;
829 }
830
831 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map, Dali::Actor sourceActor )
832 {
833   Replacement replacement(map, mReplacementMap);
834   return CreateAnimation( animationName, replacement, sourceActor);
835 }
836
837 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map )
838 {
839   Replacement replacement(map, mReplacementMap);
840   return CreateAnimation( animationName, replacement, Stage::GetCurrent().GetRootLayer() );
841 }
842
843 Animation Builder::CreateAnimation( const std::string& animationName, Dali::Actor sourceActor )
844 {
845   Replacement replacement( mReplacementMap );
846
847   return CreateAnimation( animationName, replacement, sourceActor );
848 }
849
850 Animation Builder::CreateAnimation( const std::string& animationName )
851 {
852   Replacement replacement( mReplacementMap );
853
854   return CreateAnimation( animationName, replacement, Dali::Stage::GetCurrent().GetRootLayer() );
855 }
856
857 void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::UIFormat format )
858 {
859   DALI_ASSERT_ALWAYS( format == Dali::Toolkit::Builder::JSON && "Currently only JSON is supported" );
860
861   // parser to get constants and includes only
862   Dali::Toolkit::JsonParser parser = Dali::Toolkit::JsonParser::New();
863
864   if( !parser.Parse( data ) )
865   {
866     DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
867                       parser.GetErrorLineNumber(),
868                       parser.GetErrorColumn(),
869                       parser.GetErrorDescription().c_str() );
870
871     DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
872
873   }
874   else
875   {
876     // load constant map (allows the user to override the constants in the json after loading)
877     LoadConstants( *parser.GetRoot(), mReplacementMap );
878
879     // merge includes
880     if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) )
881     {
882       Replacement replacer( mReplacementMap );
883
884       for(TreeNode::ConstIterator iter = (*includes).CBegin(); iter != (*includes).CEnd(); ++iter)
885       {
886         OptionalString filename = replacer.IsString( (*iter).second );
887
888         if( filename )
889         {
890 #if defined(DEBUG_ENABLED)
891           DALI_SCRIPT_VERBOSE("Loading Include '%s'\n", (*filename).c_str());
892 #endif
893           LoadFromString( GetFileContents(*filename) );
894         }
895       }
896     }
897
898     if( !mParser.Parse( data ) )
899     {
900       DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
901                         mParser.GetErrorLineNumber(),
902                         mParser.GetErrorColumn(),
903                         mParser.GetErrorDescription().c_str() );
904
905       DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
906     }
907   }
908
909   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
910
911 }
912
913 void Builder::AddConstants( const PropertyValueMap& map )
914 {
915   for(PropertyValueMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
916   {
917     mReplacementMap[ (*iter).first ] = (*iter).second;
918   }
919 }
920
921 void Builder::AddConstant( const std::string& key, const Property::Value& value )
922 {
923   mReplacementMap[key] = value;
924 }
925
926 const PropertyValueMap& Builder::GetConstants() const
927 {
928   return mReplacementMap;
929 }
930
931 const Property::Value& Builder::GetConstant( const std::string& key ) const
932 {
933   PropertyValueMap::const_iterator iter = mReplacementMap.find( key );
934   if( iter  != mReplacementMap.end() )
935   {
936     return (*iter).second;
937   }
938   else
939   {
940     static Property::Value invalid;
941     return invalid;
942   }
943 }
944
945 void Builder::LoadConstants( const TreeNode& root, PropertyValueMap& intoMap )
946 {
947   Replacement replacer(intoMap);
948
949   if( OptionalChild constants = IsChild(root, "constants") )
950   {
951     for(TreeNode::ConstIterator iter = (*constants).CBegin();
952         iter != (*constants).CEnd(); ++iter)
953     {
954       Dali::Property::Value property;
955       if( (*iter).second.GetName() )
956       {
957 #if defined(DEBUG_ENABLED)
958         DALI_SCRIPT_VERBOSE("Constant set from json '%s'\n", (*iter).second.GetName());
959 #endif
960         if( SetPropertyFromNode( (*iter).second, property, replacer ) )
961         {
962           intoMap[ (*iter).second.GetName() ] = property;
963         }
964         else
965         {
966           DALI_SCRIPT_WARNING("Cannot convert property for constant %s\n",
967                               (*iter).second.GetName() == NULL ? "no name?" : (*iter).second.GetName());
968         }
969       }
970     }
971   }
972
973 #if defined(DEBUG_ENABLED)
974   PropertyValueMap::const_iterator iter = intoMap.find( "CONFIG_SCRIPT_LOG_LEVEL" );
975   if( iter != intoMap.end() && (*iter).second.GetType() == Property::STRING )
976   {
977     std::string logLevel( (*iter).second.Get< std::string >() );
978     if( logLevel == "NoLogging" )
979     {
980       gFilterScript->SetLogLevel( Integration::Log::NoLogging );
981     }
982     else if( logLevel == "Concise" )
983     {
984       gFilterScript->SetLogLevel( Integration::Log::Concise );
985     }
986     else if( logLevel == "General" )
987     {
988       gFilterScript->SetLogLevel( Integration::Log::General );
989     }
990     else if( logLevel == "Verbose" )
991     {
992       gFilterScript->SetLogLevel( Integration::Log::Verbose );
993     }
994   }
995 #endif
996
997 }
998
999 bool Builder::ApplyStyle( const std::string& styleName, Handle& handle )
1000 {
1001   Replacement replacer( mReplacementMap );
1002   return ApplyStyle( styleName, handle, replacer );
1003 }
1004
1005 bool Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement )
1006 {
1007   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1008
1009   OptionalChild styles = IsChild( *mParser.GetRoot(), KEYNAME_STYLES );
1010   OptionalChild style  = IsChild( *styles, styleName );
1011
1012   if( styles && style )
1013   {
1014     ApplyAllStyleProperties( *mParser.GetRoot(), *style, handle, replacement );
1015     return true;
1016   }
1017   else
1018   {
1019     DALI_SCRIPT_WARNING("No styles section to create style '%s'\n", styleName.c_str());
1020     return false;
1021   }
1022 }
1023
1024 BaseHandle Builder::Create( const std::string& templateName, const PropertyValueMap& map )
1025 {
1026   Replacement replacement( map, mReplacementMap );
1027   return Create( templateName, replacement );
1028 }
1029
1030 BaseHandle Builder::Create( const std::string& templateName, const Replacement& constant )
1031 {
1032   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1033
1034   BaseHandle baseHandle;
1035
1036   OptionalChild templates = IsChild(*mParser.GetRoot(), KEYNAME_TEMPLATES);
1037
1038   if( !templates )
1039   {
1040     DALI_SCRIPT_WARNING("No template section found to CreateFromTemplate\n");
1041   }
1042   else
1043   {
1044     OptionalChild childTemplate = IsChild(*templates, templateName);
1045     if(!childTemplate)
1046     {
1047       DALI_SCRIPT_WARNING("Template '%s' does not exist in template section\n", templateName.c_str());
1048     }
1049     else
1050     {
1051       OptionalString type = constant.IsString( IsChild(*childTemplate, KEYNAME_TYPE) );
1052
1053       if(!type)
1054       {
1055         DALI_SCRIPT_WARNING("Cannot create template '%s' as template section is missing 'type'\n", templateName.c_str());
1056       }
1057       else
1058       {
1059         baseHandle = DoCreate( *mParser.GetRoot(), *childTemplate, Actor(), constant );
1060       }
1061     }
1062   }
1063
1064   return baseHandle;
1065 }
1066
1067
1068 BaseHandle Builder::Create( const std::string& templateName )
1069 {
1070   Replacement replacement( mReplacementMap );
1071   return Create( templateName, replacement );
1072 }
1073
1074 Builder::Builder()
1075 : mSlotDelegate( this )
1076 {
1077   mParser = Dali::Toolkit::JsonParser::New();
1078 }
1079
1080 Builder::~Builder()
1081 {
1082 }
1083
1084 } // namespace Internal
1085
1086 } // namespace Toolkit
1087
1088 } // namespace Dali