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