JavaScript support for DALi
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / utils / v8-utils.cpp
1 /*
2  * Copyright (c) 2015 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 // HEADER
19 #include "v8-utils.h"
20
21 // EXTERNAL INCLUDES
22 #include <iostream>
23 #include <fstream>
24 #include <sstream>
25 #include <dali/integration-api/debug.h>
26
27 // INTERNAL INCLUDES
28 #include <object/property-value-wrapper.h>
29 #include <actors/actor-wrapper.h>
30 #include <object/handle-wrapper.h>
31 #include <image/image-wrapper.h>
32 #include <render-tasks/render-task-wrapper.h>
33 #include <object/property-value-wrapper.h>
34
35
36 /**
37  * Similar to DALI_LOG_ERROR except the PRETTY_FUNCTION
38  * is removed because it makes no sense for scripting errors.
39  */
40 #define DALI_LOG_SCRIPT_ERROR(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ## args)
41
42 namespace Dali
43 {
44
45 namespace V8Plugin
46 {
47
48 namespace V8Utils
49 {
50
51 void Log(const v8::FunctionCallbackInfo< v8::Value >& args)
52 {
53   v8::HandleScope handleScope( args.GetIsolate());
54
55   bool first = true;
56   for (int i = 0; i < args.Length(); i++)
57   {
58     if (first)
59     {
60       first = false;
61     }
62     else
63     {
64       std::cout << " ";
65     }
66     v8::String::Utf8Value utf8_value( args[i] );
67     std::cout << *utf8_value;
68   }
69 }
70
71 void LogError(const v8::FunctionCallbackInfo< v8::Value >& args)
72 {
73   v8::HandleScope handleScope( args.GetIsolate());
74   std::string output;
75   bool first = true;
76   for (int i = 0; i < args.Length(); i++)
77   {
78     if (first)
79     {
80       first = false;
81     }
82     else
83     {
84       output +=" ";
85     }
86     v8::String::Utf8Value utf8_value( args[i] );
87     output += *utf8_value;
88   }
89   DALI_LOG_ERROR_NOFN( "JavaScript: %s",output.c_str() );
90 }
91
92 void GetFileContents(const std::string &fileName, std::string& contents)
93 {
94    std::ifstream t(fileName.c_str());
95    contents = std::string((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
96 };
97
98 void GetFileDirectory( const std::string& fileName, std::string& directory )
99 {
100   directory = "";
101
102   // get the position of the last slash
103   size_t pos = fileName.find_last_of("\\/");
104
105   // if it doesn't exist, return nothing
106   if( (std::string::npos == pos ) )
107   {
108     return;
109   }
110   else
111   {
112     // check an edge case where the string ends in a forward slash "mydir/"
113     if( (pos+1) < fileName.length() )
114     {
115       directory = fileName.substr(0, pos+1);
116       return;
117     }
118   }
119 }
120
121 void GetFileName( const std::string& fullPathName, std::string& fileName )
122 {
123   // look for last slash
124   size_t pos = fullPathName.find_last_of("\\/");
125
126   if( std::string::npos == pos )
127   {
128     fileName = fullPathName;
129   }
130   else
131   {
132     fileName = fullPathName.substr(pos,fileName.length());
133   }
134 }
135
136 void GetModuleName( const std::string& fileName, std::string& moduleName )
137 {
138   std::string fileNameNoPath;
139    GetFileName( fileName , fileNameNoPath );
140   size_t pos = fileNameNoPath.find_last_of(".");
141   if( std::string::npos == pos )
142   {
143     moduleName = fileNameNoPath;
144   }
145   else
146   {
147     moduleName = fileName.substr(0, pos );
148   }
149 }
150
151 void ReportException(  v8::Isolate* isolate, v8::TryCatch* tryCatch)
152 {
153   v8::HandleScope handleScope( isolate );
154
155   v8::String::Utf8Value exception(tryCatch->Exception());
156   v8::Handle<v8::Message> message   = tryCatch->Message();
157
158   if (message.IsEmpty())
159   {
160     // V8 didn't provide any extra information about this error; just
161     // print the exception.
162     DALI_LOG_SCRIPT_ERROR("%s\n", *exception);
163   }
164   else
165   {
166
167     // Print (filename):(line number): (message).
168     v8::String::Utf8Value filename(message->GetScriptResourceName());
169
170     DALI_LOG_SCRIPT_ERROR("\n\n====== Error found in JavaScript: ========= \n");
171
172
173     int linenum = message->GetLineNumber();
174     DALI_LOG_SCRIPT_ERROR("File: %s\n", *filename, linenum, *exception);
175
176      DALI_LOG_SCRIPT_ERROR("Error: :%s\n", *exception );
177      DALI_LOG_SCRIPT_ERROR("Line: :%i\n",  linenum );
178
179     // Print line of source code.
180     v8::String::Utf8Value sourceline(message->GetSourceLine());
181
182     DALI_LOG_SCRIPT_ERROR("Source: %s\n", *sourceline);
183
184     // Print wavy underline (GetUnderline is deprecated).
185
186     std::stringstream msg;
187
188     int start = message->GetStartColumn();
189     for (int i = 0; i < start; i++)
190     {
191       msg << " ";
192     }
193     int end = message->GetEndColumn();
194     for (int i = start; i < end; i++)
195     {
196       msg << "↑";
197     }
198
199     DALI_LOG_SCRIPT_ERROR("        %s\n", msg.str().c_str());
200
201     v8::String::Utf8Value stack_trace(tryCatch->StackTrace());
202     if (stack_trace.length() > 0)
203     {
204       DALI_LOG_SCRIPT_ERROR("%s\n", *stack_trace);
205     }
206     DALI_LOG_SCRIPT_ERROR("\n=========================================== \n");
207
208   }
209 }
210
211 std::string GetJavaScriptFunctionName( const char* functionName  )
212 {
213   // @todo if we are 100% decided on lower case, go through
214   // every api and manually change the function names to lower case first character
215   std::string name( functionName );
216   name[0]=tolower( functionName[0] );
217   return name;
218 }
219
220 void Version(const v8::FunctionCallbackInfo< v8::Value >& args)
221 {
222   v8::HandleScope handleScope( args.GetIsolate());
223
224   v8::Handle<v8::String>  ver = v8::String::NewFromUtf8(args.GetIsolate(), v8::V8::GetVersion());
225
226   args.GetReturnValue().Set(ver);
227 }
228
229
230 std::string v8StringToStdString( const v8::Handle<v8::Value>& value )
231 {
232   v8::String::Utf8Value utf8(value);
233   return std::string(*utf8);
234 }
235
236
237 std::string PropertyNameToJavaScriptName(const std::string& hyphenatedName)
238 {
239   std::string ret;
240
241   ret.reserve(hyphenatedName.size());
242
243   bool capitlizeNext = false ;
244   for(unsigned int i = 0; i < hyphenatedName.size(); ++i)
245   {
246     char c = hyphenatedName[i];
247     if(c == '-')
248     {
249       capitlizeNext = true;
250     }
251     else
252     {
253       if(capitlizeNext)
254       {
255         ret.push_back(std::toupper(c));
256         capitlizeNext = false;
257       }
258       else
259       {
260         ret.push_back(c);
261       }
262     }
263   }
264
265   return ret;
266 }
267
268
269
270 std::string JavaScriptNameToPropertyName(const std::string& camelCase)
271 {
272   std::string ret;
273
274   int countUpper = 0;
275   for(unsigned int i = 0; i < camelCase.size(); ++i)
276   {
277     if(std::isupper(camelCase[i]))
278     {
279       countUpper++;
280     }
281   }
282
283   if(countUpper)
284   {
285     ret.reserve(camelCase.size() + countUpper);
286
287     for(unsigned int i = 0; i < camelCase.size(); ++i)
288     {
289       char c = camelCase[i];
290       if(std::isupper(c))
291       {
292         ret.push_back('-');
293       }
294
295       ret.push_back(std::tolower(c));
296     }
297   }
298   else
299   {
300     return camelCase ;
301   }
302
303   return ret;
304 }
305
306 void ScriptError( const char* function, v8::Isolate* isolate, std::string errorString )
307 {
308   v8::EscapableHandleScope scope( isolate);
309   std::string errorMsg = std::string(function) + std::string("(), ") + errorString;
310
311   // log out to DALI_LOG_ERROR first, so we know something has gone wrong
312   DALI_LOG_ERROR("%s \n", errorMsg.c_str() );
313
314   // throw a V8 exception, DALi will keep running but we will get a print out
315   // of where the error occured in the JavaScript source
316   isolate->ThrowException( v8::String::NewFromUtf8( isolate, errorMsg.c_str()) );
317 }
318
319 bool IsBooleanPrimitiveOrObject( const v8::Local<v8::Value>& value )
320 {
321   return ( value->IsBoolean() || value->IsBooleanObject());
322 }
323
324 bool GetBooleanValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
325 {
326   v8::EscapableHandleScope scope( isolate); // may not be required.
327
328   if( value->IsBoolean() )
329   {
330     return value->ToBoolean()->Value();
331   }
332   else if (value->IsBooleanObject() )
333   {
334     const v8::Local<v8::BooleanObject> object = v8::Local<v8::BooleanObject>::Cast(value);
335     return object->ValueOf();
336   }
337   DALI_SCRIPT_EXCEPTION(isolate, "no bool found");
338   return false;
339 }
340
341 bool IsNumberPrimitiveOrObject( const v8::Local<v8::Value>& value )
342 {
343   return ( value->IsNumber() || value->IsNumberObject());
344 }
345
346 float GetNumberValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
347 {
348   v8::EscapableHandleScope scope( isolate); // may not be required.
349
350   if( value->IsNumber() )
351   {
352     return value->ToNumber()->Value();
353   }
354   else if (value->IsNumberObject() )
355   {
356     const v8::Local<v8::NumberObject> object = v8::Local<v8::NumberObject>::Cast(value);
357     return object->ValueOf();
358   }
359
360   DALI_SCRIPT_EXCEPTION(isolate, "no number found?");
361   return 0.f;
362 }
363
364 bool IsStringPrimitiveOrObject( const v8::Local<v8::Value>& value )
365 {
366   return ( value->IsString() || value->IsStringObject());
367 }
368
369 std::string GetStringValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
370 {
371   v8::EscapableHandleScope scope( isolate); // may not be required.
372
373   if( value->IsString() )
374   {
375     return V8Utils::v8StringToStdString(value);
376   }
377   else if (value->IsStringObject() )
378   {
379     const v8::Local<v8::StringObject> object = v8::Local<v8::StringObject>::Cast(value);
380     return V8Utils::v8StringToStdString( object->ValueOf() );
381   }
382
383   DALI_SCRIPT_EXCEPTION(isolate, "no string found?");
384   return "";
385 }
386
387
388 Property::Value GetPropertyValueFromObject( bool& found, v8::Isolate* isolate, const   v8::Local<v8::Value >& value  )
389 {
390   v8::HandleScope handleScope( isolate);
391
392   Property::Value  daliPropertyValue;// creates a property with Property::INVALID
393
394   found = false;
395
396   if( value->IsObject() )
397   {
398     v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast( value );
399
400     if( BaseWrappedObject::IsWrappedTypeAPropertyValue( object ) )
401     {
402       found = true;
403       PropertyValueWrapper* propertyWrapper = PropertyValueWrapper::Unwrap( isolate, object );
404       return propertyWrapper->GetValue();
405     }
406     else if( value->IsArray() )
407     {
408       found = true;
409       return PropertyValueWrapper::VectorOrMatrixFromV8Array( isolate, object);//todo check for V8 array / map?
410     }
411   }
412   else if( value->IsBoolean() )
413   {
414     found = true;
415     v8::Local<v8::Boolean> v = value->ToBoolean();
416     return Dali::Property::Value(v->Value());
417   }
418   else if( value->IsNumber() )
419   {
420     found = true;
421     v8::Local<v8::Number> v = value->ToNumber();
422     return Dali::Property::Value(static_cast<float>(v->Value()));
423   }
424   else if( value->IsInt32() )
425   {
426     found = true;
427     v8::Local<v8::Int32> v = value->ToInt32();
428     return Dali::Property::Value(static_cast<int>(v->Value()));
429   }
430   else if ( value->IsUint32() )
431   {
432     found = true;
433     v8::Local<v8::Uint32> v = value->ToUint32();
434     return Dali::Property::Value(static_cast<unsigned int>(v->Value()));
435   }
436   return daliPropertyValue;
437
438 }
439
440 Property::Map GetPropertyMapFromObject( v8::Isolate* isolate, const v8::Local<v8::Object>& object)
441 {
442   v8::Local<v8::Array> properties = object->GetPropertyNames();
443   Property::Map propertyMap;    // empty map
444
445   for(  unsigned int i = 0; i <  properties->Length(); ++i)
446   {
447     // Get the key
448     v8::Local<v8::Value> key = properties->Get( i );
449     std::string keyString = v8StringToStdString( key );
450
451     // Get the value
452     v8::Local<v8::Value> value = object->Get( key );
453     std::string valueString = V8Utils::v8StringToStdString( value );
454
455     propertyMap[ keyString ] = valueString.c_str();
456
457   }
458   return propertyMap;
459 }
460
461 Actor GetActorFromObject( v8::Isolate* isolate, bool& found, v8::Local<v8::Object>& object)
462 {
463   v8::HandleScope handleScope( isolate);
464   found = false;
465
466   if( BaseWrappedObject::IsWrappedType ( isolate, object, BaseWrappedObject::ACTOR ))
467   {
468     HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, object );
469     return Actor::DownCast( handleWrapper->mHandle );
470   }
471   return Actor();
472 }
473
474
475 int GetIntegerParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args, int defaultValue  )
476 {
477   found = false;
478   unsigned int length = args.Length();
479   if( index >= length )
480   {
481     return defaultValue;
482   }
483   if( args[ index ]->IsInt32() )
484   {
485     found = true;
486     return args[ index ]->Int32Value();
487   }
488   {
489     return defaultValue;
490   }
491 }
492
493 float GetFloatParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args, float defaultValue  )
494 {
495   found = false;
496   unsigned int length = args.Length();
497   if( index >= length )
498   {
499     return defaultValue;
500   }
501   if( args[ index ]->IsNumber() )
502   {
503     found = true;
504     return args[ index ]->NumberValue();
505   }
506   {
507     return defaultValue;
508   }
509 }
510
511 std::string GetStringParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
512 {
513   found = false;
514   unsigned int length = args.Length();
515
516   if( index >= length )
517   {
518     return std::string();
519   }
520   if( args[ index ]->IsString() )
521   {
522     found = true;
523     return v8StringToStdString( args[ index ]);
524   }
525   else
526   {
527     return std::string();
528   }
529 }
530
531 bool GetBooleanParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
532 {
533   v8::HandleScope handleScope( isolate);
534
535   found = false;
536   unsigned int length = args.Length();
537   if( index >= length )
538   {
539     return false;
540   }
541   if( args[ index ]->IsBoolean() )
542   {
543     found = true;
544     v8::Local<v8::Boolean> v = args[ index ]->ToBoolean();
545     return v->Value();
546   }
547   else
548   {
549     return false;
550   }
551 }
552
553 Handle GetHandleParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
554 {
555   v8::HandleScope handleScope( isolate);
556
557   found = false;
558   unsigned int length = args.Length();
559   if( index >= length )
560   {
561     return Handle();
562   }
563
564   if( args[ index ]->IsObject() )
565   {
566     v8::Local<v8::Object> object = args[ index ]->ToObject();
567     v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
568     void* ptr = field->Value();
569     if( ptr )
570     {
571         found = true;
572         HandleWrapper* wrapper = static_cast< HandleWrapper *>(ptr);
573         return wrapper->GetHandle();
574     }
575   }
576   return Handle();
577 }
578
579 Vector2 GetVector2Parameter( unsigned int index,  bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
580 {
581   v8::HandleScope handleScope( isolate);
582   unsigned int length =  args.Length();
583   Vector2 ret;
584   found = false;
585
586   if( index < length )
587   {
588     if( args[ index ]->IsObject() )
589     {
590       Dali::Property::Value value;
591       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR2 );
592       if( value.GetType() == Dali::Property::VECTOR2)
593       {
594         found = true;
595         value.Get(ret);
596       }
597       else
598       {
599         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector2 parameter");
600       }
601     }
602   }
603   else
604   {
605     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector2 parameter");
606   }
607
608   return ret;
609 }
610
611 Vector2 GetVector2ParameterFrom2Float( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
612 {
613   Vector2 ret(0.0f,0.0f);
614   bool bFound(false);
615   unsigned int argCount( args.Length() );
616
617   if( index+2 >= argCount )
618   {
619     DALI_SCRIPT_EXCEPTION(isolate, "Missing parameter");
620   }
621
622   found = true;
623   ret.x = V8Utils::GetFloatParameter( index, bFound, isolate, args, 0.0f );
624   found = found && bFound;
625   ret.y = V8Utils::GetFloatParameter( index+1, bFound, isolate, args, 0.0f );
626   found = found && bFound;
627
628   return ret;
629 }
630
631 Vector3 GetVector3Parameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args)
632 {
633   v8::HandleScope handleScope( isolate);
634   unsigned int argCount( args.Length() );
635   Vector3 ret;
636   found = false;
637   if( index < argCount )
638   {
639     if( args[ index ]->IsObject() )
640     {
641       Dali::Property::Value value;
642       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR3 );
643       if( value.GetType() == Dali::Property::VECTOR3)
644       {
645         found = true;
646         value.Get(ret);
647       }
648       else
649       {
650         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector3 parameter");
651       }
652     }
653   }
654   else
655   {
656     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector3 parameter");
657
658   }
659
660   return ret;
661 }
662
663 Vector4 GetVector4Parameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args)
664 {
665   v8::HandleScope handleScope( isolate);
666   unsigned int argCount( args.Length() );
667   Vector4 ret;
668   found = false;
669
670   if( index < argCount )
671   {
672     if( args[ index ]->IsObject() )
673     {
674       Dali::Property::Value value;
675       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR4 );
676       if( value.GetType() == Dali::Property::VECTOR4)
677       {
678         found = true;
679         value.Get(ret);
680       }
681       else
682       {
683         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector4 parameter");
684       }
685     }
686   }
687   else
688   {
689     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector4 parameter");
690   }
691
692   return ret;
693 }
694
695
696 Rect<int> GetRectIntParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
697 {
698   v8::HandleScope handleScope( isolate);
699
700    found = false;
701    int length = args.Length() - index;
702
703    // if it's an array read the 2 numbers into a vector2
704    if( length == 4 )
705    {
706      if( args[ 0 + index ]->IsInt32() &&
707          args[ 1 + index ]->IsInt32() &&
708          args[ 2 + index ]->IsInt32() &&
709          args[ 3 + index ]->IsInt32() )
710      {
711        found = true;
712        Rect<int> rect( args[ 0 + index ]->Int32Value(),
713                        args[ 1 + index ]->Int32Value(),
714                        args[ 2 + index ]->Int32Value(),
715                        args[ 3 + index ]->Int32Value() );
716        return rect;
717      }
718    }
719    // this will extract a Vector4, if it is a Vector4 or a Javascript array object
720    if( args[ index ]->IsObject() )
721    {
722      Dali::Property::Value value;
723      value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::RECTANGLE );
724      if( value.GetType() == Dali::Property::RECTANGLE)
725      {
726        found = true;
727        Rect<int> rect;
728        value.Get(rect);
729        return rect;
730      }
731
732      // @todo support vector4 as well?
733    }
734    return Rect<int>();
735 }
736
737 Actor GetActorParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
738 {
739   BaseWrappedObject* wrapper = GetWrappedDaliObjectParameter( index, BaseWrappedObject::ACTOR, isolate, args);
740   ActorWrapper* actorWrapper = static_cast< ActorWrapper*>( wrapper );
741   if( actorWrapper )
742   {
743     found = true;
744     return actorWrapper->GetActor();
745   }
746   else
747   {
748     return Actor();
749   }
750 }
751
752 Layer GetLayerParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
753 {
754   Actor actor = GetActorParameter( index, found, isolate, args );
755   return Layer::DownCast( actor );
756 }
757
758 Image GetImageParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
759 {
760   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( index, BaseWrappedObject::IMAGE, isolate, args );
761   if( wrappedObject )
762   {
763     found = true;
764     ImageWrapper* wrapper = static_cast< ImageWrapper *>(wrappedObject);
765     return wrapper->GetImage();
766   }
767   else
768   {
769     return Image();
770   }
771
772 }
773 RenderTask GetRenderTaskParameter( unsigned int paramIndex, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
774 {
775   found = false;
776   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::RENDER_TASK, isolate, args );
777   if( wrappedObject )
778   {
779     found = true;
780     RenderTaskWrapper* wrapper = static_cast< RenderTaskWrapper *>(wrappedObject);
781     return wrapper->GetRenderTask();
782   }
783   else
784   {
785     return RenderTask(); // empty handle
786   }
787 }
788
789
790 BaseWrappedObject* GetWrappedDaliObjectParameter( unsigned int index,  BaseWrappedObject::Type type,  v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
791 {
792   v8::HandleScope handleScope( isolate);
793   unsigned int length = args.Length();
794
795   if( index >= length )
796   {
797     return NULL;
798   }
799
800   if( !args[ index ]->IsObject() )
801   {
802     return NULL;
803   }
804
805   v8::Local<v8::Object> object = args[ index ]->ToObject();
806
807   if( BaseWrappedObject::IsWrappedType ( isolate, object, type ))
808   {
809     v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
810     void* ptr = field->Value();
811     BaseWrappedObject* wrapper = static_cast< BaseWrappedObject *>(ptr);
812     return wrapper;
813   }
814   return NULL;
815 }
816
817
818 Property::Value GetPropertyValueParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
819 {
820   v8::HandleScope handleScope( isolate);
821
822   Property::Value  daliPropertyValue;// creates a property with Property::INVALID
823
824   found = false;
825   unsigned int length = args.Length();
826
827   if( index >= length )
828   {
829     return daliPropertyValue;
830   }
831   v8::Local<v8::Value > value = args[ index ];
832
833   return GetPropertyValueFromObject( found, isolate, value);
834 }
835
836 Property::Map GetPropertyMapParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
837 {
838   v8::HandleScope handleScope( isolate);
839
840   Property::Map propertyMap;    // empty map
841
842   found = false;
843   unsigned int length = args.Length();
844
845   if( index >= length )
846   {
847     return propertyMap;
848   }
849
850   if( !args[ index ]->IsObject() )
851   {
852     return propertyMap;
853   }
854   found = true;
855
856   // go through each key value pair
857   v8::Local<v8::Object> obj = args[ index ]->ToObject();
858
859   return GetPropertyMapFromObject( isolate, obj );
860
861 }
862
863 void CreatePropertyMap( v8::Isolate* isolate, const Property::Map& map, v8::Local<v8::Object>& object )
864 {
865   v8::HandleScope handleScope( isolate);
866
867   // we're converting a dali property map in to a JavaScript property map
868   if( map.Count() == 0 )
869   {
870     return;
871   }
872
873   for( unsigned int index = 0; index < map.Count() - 1; ++index )
874   {
875     const std::string& key = map.GetKey( index );
876     Property::Value& value = map.GetValue( index );
877     v8::Local<v8::Value> v8Value;
878
879     switch( value.GetType() )
880     {
881       case Dali::Property::FLOAT:
882       {
883         v8Value = v8::Number::New( isolate, value.Get<float>()  );
884         break;
885       }
886       case Dali::Property::BOOLEAN:
887       {
888         v8Value = v8::Boolean::New(  isolate, value.Get<bool>());
889         break;
890       }
891       case Dali::Property::INTEGER:
892       {
893         v8Value = v8::Integer::New( isolate, value.Get<int>());
894         break;
895       }
896       case Dali::Property::UNSIGNED_INTEGER:
897       {
898         v8Value = v8::Integer::New( isolate, value.Get<unsigned int>());
899         break;
900       }
901       case Dali::Property::STRING:
902       {
903         std::string string = value.Get< std::string >();
904         v8Value = v8::String::NewFromUtf8( isolate,  string.c_str());
905         break;
906       }
907       case Dali::Property::VECTOR2:
908       {
909         // create a vector2
910         Vector2 vec = value.Get<Vector2>();
911         v8::Local<v8::Array> array= v8::Array::New( isolate, 2 );
912         array->Set( 0 , v8::Number::New(isolate, vec.x));
913         array->Set( 1 , v8::Number::New(isolate, vec.y));
914         v8Value = array;
915         break;
916       }
917       case Dali::Property::VECTOR3:
918       {
919         // create a vector 3
920         Vector3 vec = value.Get<Vector3>();
921         v8::Local<v8::Array> array= v8::Array::New( isolate, 3 );
922         array->Set( 0 , v8::Number::New(isolate, vec.x));
923         array->Set( 1 , v8::Number::New(isolate, vec.y));
924         array->Set( 2 , v8::Number::New(isolate, vec.z));
925         v8Value = array;
926         break;
927       }
928       case Dali::Property::VECTOR4:
929       {
930         // create a vector 4
931         Vector4 vec = value.Get<Vector4>();
932         v8::Local<v8::Array> array= v8::Array::New( isolate, 4 );
933         array->Set( 0 , v8::Number::New(isolate, vec.x));
934         array->Set( 1 , v8::Number::New(isolate, vec.y));
935         array->Set( 2 , v8::Number::New(isolate, vec.z));
936         array->Set( 3 , v8::Number::New(isolate, vec.w));
937         v8Value = array;
938         break;
939       }
940
941       default:
942       {
943         DALI_SCRIPT_EXCEPTION( isolate, "Primitive mismatch \n");
944         return;
945       }
946     }
947     object->Set( v8::String::NewFromUtf8( isolate, key.c_str() ), v8Value );
948   }
949 }
950
951 void ReadFloatArguments( bool& foundAllArguments, float* data, unsigned int dataSize, const v8::FunctionCallbackInfo< v8::Value >& args, float defaultValue )
952 {
953   foundAllArguments = true;
954   unsigned int length = args.Length();
955
956   if( length < dataSize )
957   {
958     foundAllArguments = false;
959   }
960
961   for( unsigned int i = 0; i< dataSize ;i++ )
962   {
963     if( i < length )
964     {
965       if( args[ i ]->IsNumber()  )
966       {
967         data[i] = args[i]->NumberValue();
968       }
969       else
970       {
971         data[i] = defaultValue;
972         foundAllArguments = false;   // bad argument
973       }
974     }
975     else
976     {
977       data[i] = defaultValue; // not enough arguments
978     }
979   }
980
981 }
982
983 void ReadIntegerArguments( bool& foundAllArguments, int* data, int dataSize, const v8::FunctionCallbackInfo< v8::Value >& args, int defaultValue )
984 {
985   foundAllArguments = true;
986   int length = args.Length();
987   if( length < dataSize )
988   {
989     foundAllArguments = false;
990   }
991
992   for( int i = 0; i< dataSize ;i++ )
993   {
994     if( i < length )
995     {
996       if( args[ i ]->IsInt32()  )
997       {
998         data[i] = args[i]->Int32Value();
999       }
1000       else
1001       {
1002         data[i] = defaultValue;
1003         foundAllArguments = false;   // bad argument
1004       }
1005     }
1006     else
1007     {
1008       data[i] = defaultValue; // not enough arguments
1009     }
1010   }
1011
1012 }
1013 } // namespace V8Utils
1014
1015 } // namespace V8Plugin
1016
1017 } // namespace Dali