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