python api for collection add()/remove()
[blender.git] / source / blender / makesrna / intern / rna_access.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Blender Foundation (2008).
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_ID.h"
31 #include "DNA_windowmanager_types.h"
32
33 #include "BLI_blenlib.h"
34 #include "BLI_dynstr.h"
35 #include "BLI_ghash.h"
36
37 #include "BKE_context.h"
38 #include "BKE_idprop.h"
39 #include "BKE_report.h"
40 #include "BKE_utildefines.h"
41
42 #include "WM_api.h"
43
44 #include "RNA_access.h"
45 #include "RNA_define.h"
46 #include "RNA_types.h"
47
48 #include "rna_internal.h"
49
50 /* Init/Exit */
51
52 void RNA_init()
53 {
54         StructRNA *srna;
55         PropertyRNA *prop;
56
57         for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
58                 if(!srna->cont.prophash) {
59                         srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
60
61                         for(prop=srna->cont.properties.first; prop; prop=prop->next)
62                                 if(!(prop->flag & PROP_BUILTIN))
63                                         BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
64                 }
65         }
66 }
67
68 void RNA_exit()
69 {
70         StructRNA *srna;
71
72         for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
73                 if(srna->cont.prophash) {
74                         BLI_ghash_free(srna->cont.prophash, NULL, NULL);
75                         srna->cont.prophash= NULL;
76                 }
77         }
78
79         RNA_free(&BLENDER_RNA);
80 }
81
82 /* Pointer */
83
84 PointerRNA PointerRNA_NULL = {{0}, 0, 0};
85
86 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
87 {
88         r_ptr->id.data= NULL;
89         r_ptr->type= &RNA_Main;
90         r_ptr->data= main;
91 }
92
93 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
94 {
95         PointerRNA tmp;
96         StructRNA *type, *idtype= NULL;
97
98         if(id) {
99                 memset(&tmp, 0, sizeof(tmp));
100                 tmp.data= id;
101                 idtype= rna_ID_refine(&tmp);
102                 
103                 while(idtype->refine) {
104                         type= idtype->refine(&tmp);
105
106                         if(type == idtype)
107                                 break;
108                         else
109                                 idtype= type;
110                 }
111         }
112         
113         r_ptr->id.data= id;
114         r_ptr->type= idtype;
115         r_ptr->data= id;
116 }
117
118 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
119 {
120         PointerRNA tmp;
121         StructRNA *idtype= NULL;
122
123         if(id) {
124                 memset(&tmp, 0, sizeof(tmp));
125                 tmp.data= id;
126                 idtype= rna_ID_refine(&tmp);
127         }
128
129         r_ptr->id.data= id;
130         r_ptr->type= type;
131         r_ptr->data= data;
132
133         if(data) {
134                 while(r_ptr->type && r_ptr->type->refine) {
135                         StructRNA *rtype= r_ptr->type->refine(r_ptr);
136
137                         if(rtype == r_ptr->type)
138                                 break;
139                         else
140                                 r_ptr->type= rtype;
141                 }
142         }
143 }
144
145 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
146 {
147         if(type && type->flag & STRUCT_ID) {
148                 ptr->id.data= ptr->data;
149         }
150         else {
151                 ptr->id.data= parent->id.data;
152         }
153 }
154
155 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
156 {
157         r_ptr->id.data= NULL;
158         r_ptr->type= &RNA_BlenderRNA;
159         r_ptr->data= &BLENDER_RNA;
160 }
161
162 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
163 {
164         PointerRNA result;
165
166         if(data) {
167                 result.data= data;
168                 result.type= type;
169                 rna_pointer_inherit_id(type, ptr, &result);
170
171                 while(result.type->refine) {
172                         type= result.type->refine(&result);
173
174                         if(type == result.type)
175                                 break;
176                         else
177                                 result.type= type;
178                 }
179         }
180         else
181                 memset(&result, 0, sizeof(result));
182         
183         return result;
184 }
185
186 /* ID Properties */
187
188 IDProperty *RNA_struct_idproperties(PointerRNA *ptr, int create)
189 {
190         StructRNA *type= ptr->type;
191
192         if(type && type->idproperties)
193                 return type->idproperties(ptr, create);
194         
195         return NULL;
196 }
197
198 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
199 {
200         IDProperty *group= RNA_struct_idproperties(ptr, 0);
201         IDProperty *idprop;
202
203         if(group) {
204                 for(idprop=group->data.group.first; idprop; idprop=idprop->next)
205                         if(strcmp(idprop->name, name) == 0)
206                                 return idprop;
207         }
208         
209         return NULL;
210 }
211
212 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
213 {
214         if(prop->magic == RNA_MAGIC) {
215                 int arraylen[RNA_MAX_ARRAY_DIMENSION];
216                 return (prop->getlength)? prop->getlength(ptr, arraylen): prop->totarraylength;
217         }
218         else {
219                 IDProperty *idprop= (IDProperty*)prop;
220
221                 if(idprop->type == IDP_ARRAY)
222                         return idprop->len;
223                 else
224                         return 0;
225         }
226 }
227
228 static int rna_ensure_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
229 {
230         if(prop->magic == RNA_MAGIC) {
231                 return (prop->getlength || prop->totarraylength) ? 1:0;
232         }
233         else {
234                 IDProperty *idprop= (IDProperty*)prop;
235
236                 return idprop->type == IDP_ARRAY ? 1:0;
237         }
238 }
239
240 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
241 {
242         if(prop->magic == RNA_MAGIC) {
243                 if(prop->getlength)
244                         prop->getlength(ptr, length);
245                 else
246                         memcpy(length, prop->arraylength, prop->arraydimension*sizeof(int));
247         }
248         else {
249                 IDProperty *idprop= (IDProperty*)prop;
250
251                 if(idprop->type == IDP_ARRAY)
252                         length[0]= idprop->len;
253                 else
254                         length[0]= 0;
255         }
256 }
257
258 static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
259 {
260         /* this verifies if the idproperty actually matches the property
261          * description and otherwise removes it. this is to ensure that
262          * rna property access is type safe, e.g. if you defined the rna
263          * to have a certain array length you can count on that staying so */
264         
265         switch(idprop->type) {
266                 case IDP_IDPARRAY:
267                         if(prop->type != PROP_COLLECTION)
268                                 return 0;
269                         break;
270                 case IDP_ARRAY:
271                         if(rna_ensure_property_array_length(ptr, prop) != idprop->len)
272                                 return 0;
273
274                         if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
275                                 return 0;
276                         if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
277                                 return 0;
278
279                         break;
280                 case IDP_INT:
281                         if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
282                                 return 0;
283                         break;
284                 case IDP_FLOAT:
285                 case IDP_DOUBLE:
286                         if(prop->type != PROP_FLOAT)
287                                 return 0;
288                         break;
289                 case IDP_STRING:
290                         if(prop->type != PROP_STRING)
291                                 return 0;
292                         break;
293                 case IDP_GROUP:
294                         if(prop->type != PROP_POINTER)
295                                 return 0;
296                         break;
297                 default:
298                         return 0;
299         }
300
301         return 1;
302 }
303
304 static PropertyRNA *typemap[IDP_NUMTYPES] =
305         {(PropertyRNA*)&rna_IDProperty_string,
306          (PropertyRNA*)&rna_IDProperty_int,
307          (PropertyRNA*)&rna_IDProperty_float,
308          NULL, NULL, NULL,
309          (PropertyRNA*)&rna_IDProperty_group, NULL,
310          (PropertyRNA*)&rna_IDProperty_double};
311
312 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
313         {NULL, (PropertyRNA*)&rna_IDProperty_int_array,
314          (PropertyRNA*)&rna_IDProperty_float_array,
315          NULL, NULL, NULL,
316          (PropertyRNA*)&rna_IDProperty_collection, NULL,
317          (PropertyRNA*)&rna_IDProperty_double_array};
318
319 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
320 {
321         /* This is quite a hack, but avoids some complexity in the API. we
322          * pass IDProperty structs as PropertyRNA pointers to the outside.
323          * We store some bytes in PropertyRNA structs that allows us to
324          * distinguish it from IDProperty structs. If it is an ID property,
325          * we look up an IDP PropertyRNA based on the type, and set the data
326          * pointer to the IDProperty. */
327
328         if((*prop)->magic == RNA_MAGIC) {
329                 if((*prop)->flag & PROP_IDPROPERTY) {
330                         IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
331
332                         if(idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
333                                 IDProperty *group= RNA_struct_idproperties(ptr, 0);
334
335                                 IDP_RemFromGroup(group, idprop);
336                                 IDP_FreeProperty(idprop);
337                                 MEM_freeN(idprop);
338                                 return NULL;
339                         }
340
341                         return idprop;
342                 }
343                 else
344                         return NULL;
345         }
346
347         {
348                 IDProperty *idprop= (IDProperty*)(*prop);
349
350                 if(idprop->type == IDP_ARRAY)
351                         *prop= arraytypemap[(int)(idprop->subtype)];
352                 else 
353                         *prop= typemap[(int)(idprop->type)];
354
355                 return idprop;
356         }
357 }
358
359 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
360 {
361         /* the quick version if we don't need the idproperty */
362
363         if(prop->magic == RNA_MAGIC)
364                 return prop;
365
366         {
367                 IDProperty *idprop= (IDProperty*)prop;
368
369                 if(idprop->type == IDP_ARRAY)
370                         return arraytypemap[(int)(idprop->subtype)];
371                 else 
372                         return typemap[(int)(idprop->type)];
373         }
374 }
375
376 static const char *rna_ensure_property_identifier(PropertyRNA *prop)
377 {
378         if(prop->magic == RNA_MAGIC)
379                 return prop->identifier;
380         else
381                 return ((IDProperty*)prop)->name;
382 }
383
384 static const char *rna_ensure_property_description(PropertyRNA *prop)
385 {
386         if(prop->magic == RNA_MAGIC)
387                 return prop->description;
388         else
389                 return ((IDProperty*)prop)->name; /* XXX - not correct */
390 }
391
392 static const char *rna_ensure_property_name(PropertyRNA *prop)
393 {
394         if(prop->magic == RNA_MAGIC)
395                 return prop->name;
396         else
397                 return ((IDProperty*)prop)->name;
398 }
399
400 /* Structs */
401
402 const char *RNA_struct_identifier(StructRNA *type)
403 {
404         return type->identifier;
405 }
406
407 const char *RNA_struct_ui_name(StructRNA *type)
408 {
409         return type->name;
410 }
411
412 int RNA_struct_ui_icon(StructRNA *type)
413 {
414         if(type)
415                 return type->icon;
416         else
417                 return ICON_DOT;
418 }
419
420 const char *RNA_struct_ui_description(StructRNA *type)
421 {
422         return type->description;
423 }
424
425 PropertyRNA *RNA_struct_name_property(StructRNA *type)
426 {
427         return type->nameproperty;
428 }
429
430 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
431 {
432         return type->iteratorproperty;
433 }
434
435 StructRNA *RNA_struct_base(StructRNA *type)
436 {
437         return type->base;
438 }
439
440 int RNA_struct_is_ID(StructRNA *type)
441 {
442         return (type->flag & STRUCT_ID) != 0;
443 }
444
445 int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
446 {
447         StructRNA *base;
448
449         if(!type)
450                 return 0;
451
452         /* ptr->type is always maximally refined */
453         for(base=type; base; base=base->base)
454                 if(base == srna)
455                         return 1;
456         
457         return 0;
458 }
459
460 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
461 {
462         PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
463         PointerRNA propptr;
464
465         if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
466                 return propptr.data;
467         
468         return NULL;
469 }
470
471 /* Find the property which uses the given nested struct */
472 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
473 {
474         PropertyRNA *prop= NULL;
475
476         RNA_STRUCT_BEGIN(ptr, iprop) {
477                 /* This assumes that there can only be one user of this nested struct */
478                 if (RNA_property_pointer_type(ptr, iprop) == srna) {
479                         prop= iprop;
480                         break;
481                 }
482         }
483         RNA_PROP_END;
484
485         return prop;
486 }
487
488 const struct ListBase *RNA_struct_defined_properties(StructRNA *srna)
489 {
490         return &srna->cont.properties;
491 }
492
493 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
494 {
495         PointerRNA tptr;
496         PropertyRNA *iterprop;
497         FunctionRNA *func;
498
499         RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
500         iterprop= RNA_struct_find_property(&tptr, "functions");
501
502         func= NULL;
503
504         RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
505                 if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
506                         func= funcptr.data;
507                         break;
508                 }
509         }
510         RNA_PROP_END;
511
512         return func;
513 }
514
515 const struct ListBase *RNA_struct_defined_functions(StructRNA *srna)
516 {
517         return &srna->functions;
518 }
519
520 StructRegisterFunc RNA_struct_register(StructRNA *type)
521 {
522         return type->reg;
523 }
524
525 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
526 {
527         do {
528                 if(type->unreg)
529                         return type->unreg;
530         } while((type=type->base));
531
532         return NULL;
533 }
534
535 void *RNA_struct_py_type_get(StructRNA *srna)
536 {
537         return srna->py_type;
538 }
539
540 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
541 {
542         srna->py_type= py_type;
543 }
544
545 void *RNA_struct_blender_type_get(StructRNA *srna)
546 {
547         return srna->blender_type;
548 }
549
550 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
551 {
552         srna->blender_type= blender_type;
553 }
554
555 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
556 {
557         PropertyRNA *nameprop;
558
559         if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
560                 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
561
562         return NULL;
563 }
564
565 /* Property Information */
566
567 const char *RNA_property_identifier(PropertyRNA *prop)
568 {
569         return rna_ensure_property_identifier(prop);
570 }
571
572 const char *RNA_property_description(PropertyRNA *prop)
573 {
574         return rna_ensure_property_description(prop);
575 }
576
577 PropertyType RNA_property_type(PropertyRNA *prop)
578 {
579         return rna_ensure_property(prop)->type;
580 }
581
582 PropertySubType RNA_property_subtype(PropertyRNA *prop)
583 {
584         return rna_ensure_property(prop)->subtype;
585 }
586
587 PropertyUnit RNA_property_unit(PropertyRNA *prop)
588 {
589         return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
590 }
591
592 int RNA_property_flag(PropertyRNA *prop)
593 {
594         return rna_ensure_property(prop)->flag;
595 }
596
597 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
598 {
599         return rna_ensure_property_array_length(ptr, prop);
600 }
601
602 int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
603 {
604         return rna_ensure_property_array_check(ptr, prop);
605 }
606
607 /* used by BPY to make an array from the python object */
608 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
609 {
610         PropertyRNA *rprop= rna_ensure_property(prop);
611
612         if(length && rprop->arraydimension > 1)
613                 rna_ensure_property_multi_array_length(ptr, prop, length);
614
615         return rprop->arraydimension;
616 }
617
618 /* Return the size of Nth dimension. */
619 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
620 {
621         int len[RNA_MAX_ARRAY_DIMENSION];
622
623         rna_ensure_property_multi_array_length(ptr, prop, len);
624
625         return len[dim];
626 }
627
628 char RNA_property_array_item_char(PropertyRNA *prop, int index)
629 {
630         const char *vectoritem= "XYZW";
631         const char *quatitem= "WXYZ";
632         const char *coloritem= "RGBA";
633         PropertySubType subtype= rna_ensure_property(prop)->subtype;
634
635         /* get string to use for array index */
636         if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE))
637                 return quatitem[index];
638         else if((index < 4) && ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
639                 return vectoritem[index];
640         else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_RGB))
641                 return coloritem[index];
642         else
643                 return '\0';
644 }
645
646 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
647 {
648         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
649
650         if(iprop->range) {
651                 iprop->range(ptr, hardmin, hardmax);
652         }
653         else {
654                 *hardmin= iprop->hardmin;
655                 *hardmax= iprop->hardmax;
656         }
657 }
658
659 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
660 {
661         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
662         int hardmin, hardmax;
663         
664         if(iprop->range) {
665                 iprop->range(ptr, &hardmin, &hardmax);
666                 *softmin= MAX2(iprop->softmin, hardmin);
667                 *softmax= MIN2(iprop->softmax, hardmax);
668         }
669         else {
670                 *softmin= iprop->softmin;
671                 *softmax= iprop->softmax;
672         }
673
674         *step= iprop->step;
675 }
676
677 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
678 {
679         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
680
681         if(fprop->range) {
682                 fprop->range(ptr, hardmin, hardmax);
683         }
684         else {
685                 *hardmin= fprop->hardmin;
686                 *hardmax= fprop->hardmax;
687         }
688 }
689
690 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
691 {
692         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
693         float hardmin, hardmax;
694
695         if(fprop->range) {
696                 fprop->range(ptr, &hardmin, &hardmax);
697                 *softmin= MAX2(fprop->softmin, hardmin);
698                 *softmax= MIN2(fprop->softmax, hardmax);
699         }
700         else {
701                 *softmin= fprop->softmin;
702                 *softmax= fprop->softmax;
703         }
704
705         *step= fprop->step;
706         *precision= (float)fprop->precision;
707 }
708
709 int RNA_property_string_maxlength(PropertyRNA *prop)
710 {
711         StringPropertyRNA *sprop= (StringPropertyRNA*)rna_ensure_property(prop);
712         return sprop->maxlength;
713 }
714
715 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
716 {
717         prop= rna_ensure_property(prop);
718
719         if(prop->type == PROP_POINTER) {
720                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
721
722                 if(pprop->typef)
723                         return pprop->typef(ptr);
724                 else if(pprop->type)
725                         return pprop->type;
726         }
727         else if(prop->type == PROP_COLLECTION) {
728                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
729
730                 if(cprop->type)
731                         return cprop->type;
732         }
733
734         return &RNA_UnknownType;
735 }
736
737 /* Reuse for dynamic types  */
738 EnumPropertyItem DummyRNA_NULL_items[] = {
739         {0, NULL, 0, NULL, NULL}
740 };
741
742 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
743 {
744         EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop);
745
746         *free= 0;
747
748         if(eprop->itemf && C) {
749                 int tot= 0;
750                 *item= eprop->itemf(C, ptr, free);
751
752                 if(totitem) {
753                         if(*item) {
754                                 for( ; (*item)[tot].identifier; tot++);
755                         }
756
757                         *totitem= tot;
758                 }
759         }
760         else {
761                 *item= eprop->item;
762                 if(totitem)
763                         *totitem= eprop->totitem;
764         }
765 }
766
767 int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
768 {       
769         EnumPropertyItem *item;
770         int free;
771         
772         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
773         
774         for(; item->identifier; item++) {
775                 if(item->identifier[0] && strcmp(item->identifier, identifier)==0) {
776                         *value = item->value;
777                         return 1;
778                 }
779         }
780
781         if(free)
782                 MEM_freeN(item);
783
784         return 0;
785 }
786
787 int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
788 {
789         for (; item->identifier; item++) {
790                 if(item->identifier[0] && item->value==value) {
791                         *identifier = item->identifier;
792                         return 1;
793                 }
794         }
795         return 0;
796 }
797
798 int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
799 {
800         for (; item->identifier; item++) {
801                 if(item->identifier[0] && item->value==value) {
802                         *name = item->name;
803                         return 1;
804                 }
805         }
806         return 0;
807 }
808
809 int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
810 {       
811         EnumPropertyItem *item= NULL;
812         int result, free;
813         
814         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
815         if(item) {
816                 result= RNA_enum_identifier(item, value, identifier);
817                 if(free)
818                         MEM_freeN(item);
819
820                 return result;
821         }
822         return 0;
823 }
824
825 const char *RNA_property_ui_name(PropertyRNA *prop)
826 {
827         return rna_ensure_property_name(prop);
828 }
829
830 const char *RNA_property_ui_description(PropertyRNA *prop)
831 {
832         return rna_ensure_property(prop)->description;
833 }
834
835 int RNA_property_ui_icon(PropertyRNA *prop)
836 {
837         return rna_ensure_property(prop)->icon;
838 }
839
840 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
841 {
842         ID *id;
843         int flag;
844
845         prop= rna_ensure_property(prop);
846
847         if(prop->editable)
848                 flag= prop->editable(ptr);
849         else
850                 flag= prop->flag;
851         
852         id= ptr->id.data;
853
854         return (flag & PROP_EDITABLE) && (!id || !id->lib || (flag & PROP_LIB_EXCEPTION));
855 }
856
857 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
858 {
859         int flag;
860
861         prop= rna_ensure_property(prop);
862
863         if(!(prop->flag & PROP_ANIMATEABLE))
864                 return 0;
865
866         if(prop->editable)
867                 flag= prop->editable(ptr);
868         else
869                 flag= prop->flag;
870
871         return (flag & PROP_EDITABLE);
872 }
873
874 int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
875 {
876         /* would need to ask animation system */
877
878         return 0;
879 }
880
881 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
882 {
883         prop= rna_ensure_property(prop);
884
885         if(prop->update)
886                 prop->update(C, ptr);
887         if(prop->noteflag)
888                 WM_event_add_notifier(C, prop->noteflag, ptr->id.data);
889 }
890
891 /* Property Data */
892
893 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
894 {
895         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
896         IDProperty *idprop;
897
898         if((idprop=rna_idproperty_check(&prop, ptr)))
899                 return IDP_Int(idprop);
900         else if(bprop->get)
901                 return bprop->get(ptr);
902         else
903                 return bprop->defaultvalue;
904 }
905
906 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
907 {
908         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
909         IDProperty *idprop;
910
911         /* just incase other values are passed */
912         if(value) value= 1;
913
914         if((idprop=rna_idproperty_check(&prop, ptr)))
915                 IDP_Int(idprop)= value;
916         else if(bprop->set)
917                 bprop->set(ptr, value);
918         else if(prop->flag & PROP_EDITABLE) {
919                 IDPropertyTemplate val = {0};
920                 IDProperty *group;
921
922                 val.i= value;
923
924                 group= RNA_struct_idproperties(ptr, 1);
925                 if(group)
926                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
927         }
928 }
929
930 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
931 {
932         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
933         IDProperty *idprop;
934
935         if((idprop=rna_idproperty_check(&prop, ptr))) {
936                 if(prop->arraydimension == 0)
937                         values[0]= RNA_property_boolean_get(ptr, prop);
938                 else
939                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
940         }
941         else if(prop->arraydimension == 0)
942                 values[0]= RNA_property_boolean_get(ptr, prop);
943         else if(bprop->getarray)
944                 bprop->getarray(ptr, values);
945         else if(bprop->defaultarray)
946                 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
947         else
948                 memset(values, 0, sizeof(int)*prop->totarraylength);
949 }
950
951 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
952 {
953         int tmp[RNA_MAX_ARRAY_LENGTH];
954         int len= rna_ensure_property_array_length(ptr, prop);
955
956         if(len <= RNA_MAX_ARRAY_LENGTH) {
957                 RNA_property_boolean_get_array(ptr, prop, tmp);
958                 return tmp[index];
959         }
960         else {
961                 int *tmparray, value;
962
963                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
964                 RNA_property_boolean_get_array(ptr, prop, tmparray);
965                 value= tmparray[index];
966                 MEM_freeN(tmparray);
967
968                 return value;
969         }
970 }
971
972 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
973 {
974         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
975         IDProperty *idprop;
976
977         if((idprop=rna_idproperty_check(&prop, ptr))) {
978                 if(prop->arraydimension == 0)
979                         IDP_Int(idprop)= values[0];
980                 else
981                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
982         }
983         else if(prop->arraydimension == 0)
984                 RNA_property_boolean_set(ptr, prop, values[0]);
985         else if(bprop->setarray)
986                 bprop->setarray(ptr, values);
987         else if(prop->flag & PROP_EDITABLE) {
988                 IDPropertyTemplate val = {0};
989                 IDProperty *group;
990
991                 val.array.len= prop->totarraylength;
992                 val.array.type= IDP_INT;
993
994                 group= RNA_struct_idproperties(ptr, 1);
995                 if(group) {
996                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
997                         IDP_AddToGroup(group, idprop);
998                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
999                 }
1000         }
1001 }
1002
1003 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1004 {
1005         int tmp[RNA_MAX_ARRAY_LENGTH];
1006         int len= rna_ensure_property_array_length(ptr, prop);
1007
1008         if(len <= RNA_MAX_ARRAY_LENGTH) {
1009                 RNA_property_boolean_get_array(ptr, prop, tmp);
1010                 tmp[index]= value;
1011                 RNA_property_boolean_set_array(ptr, prop, tmp);
1012         }
1013         else {
1014                 int *tmparray;
1015
1016                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1017                 RNA_property_boolean_get_array(ptr, prop, tmparray);
1018                 tmparray[index]= value;
1019                 RNA_property_boolean_set_array(ptr, prop, tmparray);
1020                 MEM_freeN(tmparray);
1021         }
1022 }
1023
1024 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
1025 {
1026         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1027         IDProperty *idprop;
1028
1029         if((idprop=rna_idproperty_check(&prop, ptr)))
1030                 return IDP_Int(idprop);
1031         else if(iprop->get)
1032                 return iprop->get(ptr);
1033         else
1034                 return iprop->defaultvalue;
1035 }
1036
1037 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1038 {
1039         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1040         IDProperty *idprop;
1041
1042         if((idprop=rna_idproperty_check(&prop, ptr)))
1043                 IDP_Int(idprop)= value;
1044         else if(iprop->set)
1045                 iprop->set(ptr, value);
1046         else if(prop->flag & PROP_EDITABLE) {
1047                 IDPropertyTemplate val = {0};
1048                 IDProperty *group;
1049
1050                 val.i= value;
1051
1052                 group= RNA_struct_idproperties(ptr, 1);
1053                 if(group)
1054                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1055         }
1056 }
1057
1058 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1059 {
1060         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1061         IDProperty *idprop;
1062
1063         if((idprop=rna_idproperty_check(&prop, ptr))) {
1064                 if(prop->arraydimension == 0)
1065                         values[0]= RNA_property_int_get(ptr, prop);
1066                 else
1067                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1068         }
1069         else if(prop->arraydimension == 0)
1070                 values[0]= RNA_property_int_get(ptr, prop);
1071         else if(iprop->getarray)
1072                 iprop->getarray(ptr, values);
1073         else if(iprop->defaultarray)
1074                 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1075         else
1076                 memset(values, 0, sizeof(int)*prop->totarraylength);
1077 }
1078
1079 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1080 {
1081         int tmp[RNA_MAX_ARRAY_LENGTH];
1082         int len= rna_ensure_property_array_length(ptr, prop);
1083
1084         if(len <= RNA_MAX_ARRAY_LENGTH) {
1085                 RNA_property_int_get_array(ptr, prop, tmp);
1086                 return tmp[index];
1087         }
1088         else {
1089                 int *tmparray, value;
1090
1091                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1092                 RNA_property_int_get_array(ptr, prop, tmparray);
1093                 value= tmparray[index];
1094                 MEM_freeN(tmparray);
1095
1096                 return value;
1097         }
1098 }
1099
1100 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1101 {
1102         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1103         IDProperty *idprop;
1104
1105         if((idprop=rna_idproperty_check(&prop, ptr))) {
1106                 if(prop->arraydimension == 0)
1107                         IDP_Int(idprop)= values[0];
1108                 else
1109                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\
1110         }
1111         else if(prop->arraydimension == 0)
1112                 RNA_property_int_set(ptr, prop, values[0]);
1113         else if(iprop->setarray)
1114                 iprop->setarray(ptr, values);
1115         else if(prop->flag & PROP_EDITABLE) {
1116                 IDPropertyTemplate val = {0};
1117                 IDProperty *group;
1118
1119                 val.array.len= prop->totarraylength;
1120                 val.array.type= IDP_INT;
1121
1122                 group= RNA_struct_idproperties(ptr, 1);
1123                 if(group) {
1124                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1125                         IDP_AddToGroup(group, idprop);
1126                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1127                 }
1128         }
1129 }
1130
1131 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1132 {
1133         int tmp[RNA_MAX_ARRAY_LENGTH];
1134         int len= rna_ensure_property_array_length(ptr, prop);
1135
1136         if(len <= RNA_MAX_ARRAY_LENGTH) {
1137                 RNA_property_int_get_array(ptr, prop, tmp);
1138                 tmp[index]= value;
1139                 RNA_property_int_set_array(ptr, prop, tmp);
1140         }
1141         else {
1142                 int *tmparray;
1143
1144                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1145                 RNA_property_int_get_array(ptr, prop, tmparray);
1146                 tmparray[index]= value;
1147                 RNA_property_int_set_array(ptr, prop, tmparray);
1148                 MEM_freeN(tmparray);
1149         }
1150 }
1151
1152 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
1153 {
1154         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1155         IDProperty *idprop;
1156
1157         if((idprop=rna_idproperty_check(&prop, ptr))) {
1158                 if(idprop->type == IDP_FLOAT)
1159                         return IDP_Float(idprop);
1160                 else
1161                         return (float)IDP_Double(idprop);
1162         }
1163         else if(fprop->get)
1164                 return fprop->get(ptr);
1165         else
1166                 return fprop->defaultvalue;
1167 }
1168
1169 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
1170 {
1171         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1172         IDProperty *idprop;
1173
1174         if((idprop=rna_idproperty_check(&prop, ptr))) {
1175                 if(idprop->type == IDP_FLOAT)
1176                         IDP_Float(idprop)= value;
1177                 else
1178                         IDP_Double(idprop)= value;
1179         }
1180         else if(fprop->set) {
1181                 fprop->set(ptr, value);
1182         }
1183         else if(prop->flag & PROP_EDITABLE) {
1184                 IDPropertyTemplate val = {0};
1185                 IDProperty *group;
1186
1187                 val.f= value;
1188
1189                 group= RNA_struct_idproperties(ptr, 1);
1190                 if(group)
1191                         IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, (char*)prop->identifier));
1192         }
1193 }
1194
1195 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
1196 {
1197         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1198         IDProperty *idprop;
1199         int i;
1200
1201         if((idprop=rna_idproperty_check(&prop, ptr))) {
1202                 if(prop->arraydimension == 0)
1203                         values[0]= RNA_property_float_get(ptr, prop);
1204                 else if(idprop->subtype == IDP_FLOAT) {
1205                         memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
1206                 }
1207                 else {
1208                         for(i=0; i<idprop->len; i++)
1209                                 values[i]=  (float)(((double*)IDP_Array(idprop))[i]);
1210                 }
1211         }
1212         else if(prop->arraydimension == 0)
1213                 values[0]= RNA_property_float_get(ptr, prop);
1214         else if(fprop->getarray)
1215                 fprop->getarray(ptr, values);
1216         else if(fprop->defaultarray)
1217                 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
1218         else
1219                 memset(values, 0, sizeof(float)*prop->totarraylength);
1220 }
1221
1222 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1223 {
1224         float tmp[RNA_MAX_ARRAY_LENGTH];
1225         int len= rna_ensure_property_array_length(ptr, prop);
1226
1227         if(len <= RNA_MAX_ARRAY_LENGTH) {
1228                 RNA_property_float_get_array(ptr, prop, tmp);
1229                 return tmp[index];
1230         }
1231         else {
1232                 float *tmparray, value;
1233
1234                 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1235                 RNA_property_float_get_array(ptr, prop, tmparray);
1236                 value= tmparray[index];
1237                 MEM_freeN(tmparray);
1238
1239                 return value;
1240         }
1241
1242 }
1243
1244 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
1245 {
1246         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1247         IDProperty *idprop;
1248         int i;
1249
1250         if((idprop=rna_idproperty_check(&prop, ptr))) {
1251                 if(prop->arraydimension == 0)
1252                         IDP_Double(idprop)= values[0];
1253                 else if(idprop->subtype == IDP_FLOAT) {
1254                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1255                 }
1256                 else {
1257                         for(i=0; i<idprop->len; i++)
1258                                 ((double*)IDP_Array(idprop))[i]= values[i];
1259                 }
1260         }
1261         else if(prop->arraydimension == 0)
1262                 RNA_property_float_set(ptr, prop, values[0]);
1263         else if(fprop->setarray) {
1264                 fprop->setarray(ptr, values);
1265         }
1266         else if(prop->flag & PROP_EDITABLE) {
1267                 IDPropertyTemplate val = {0};
1268                 IDProperty *group;
1269
1270                 val.array.len= prop->totarraylength;
1271                 val.array.type= IDP_FLOAT;
1272
1273                 group= RNA_struct_idproperties(ptr, 1);
1274                 if(group) {
1275                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1276                         IDP_AddToGroup(group, idprop);
1277                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1278                 }
1279         }
1280 }
1281
1282 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
1283 {
1284         float tmp[RNA_MAX_ARRAY_LENGTH];
1285         int len= rna_ensure_property_array_length(ptr, prop);
1286
1287         if(len <= RNA_MAX_ARRAY_LENGTH) {
1288                 RNA_property_float_get_array(ptr, prop, tmp);
1289                 tmp[index]= value;
1290                 RNA_property_float_set_array(ptr, prop, tmp);
1291         }
1292         else {
1293                 float *tmparray;
1294
1295                 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1296                 RNA_property_float_get_array(ptr, prop, tmparray);
1297                 tmparray[index]= value;
1298                 RNA_property_float_set_array(ptr, prop, tmparray);
1299                 MEM_freeN(tmparray);
1300         }
1301 }
1302
1303 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
1304 {
1305         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1306         IDProperty *idprop;
1307
1308         if((idprop=rna_idproperty_check(&prop, ptr)))
1309                 strcpy(value, IDP_String(idprop));
1310         else if(sprop->get)
1311                 sprop->get(ptr, value);
1312         else
1313                 strcpy(value, sprop->defaultvalue);
1314 }
1315
1316 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
1317 {
1318         char *buf;
1319         int length;
1320
1321         length= RNA_property_string_length(ptr, prop);
1322
1323         if(length+1 < fixedlen)
1324                 buf= fixedbuf;
1325         else
1326                 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
1327
1328         RNA_property_string_get(ptr, prop, buf);
1329
1330         return buf;
1331 }
1332
1333 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
1334 {
1335         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1336         IDProperty *idprop;
1337
1338         if((idprop=rna_idproperty_check(&prop, ptr)))
1339                 return strlen(IDP_String(idprop));
1340         else if(sprop->length)
1341                 return sprop->length(ptr);
1342         else
1343                 return strlen(sprop->defaultvalue);
1344 }
1345
1346 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
1347 {
1348         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1349         IDProperty *idprop;
1350
1351         if((idprop=rna_idproperty_check(&prop, ptr)))
1352                 IDP_AssignString(idprop, (char*)value);
1353         else if(sprop->set)
1354                 sprop->set(ptr, value);
1355         else if(prop->flag & PROP_EDITABLE) {
1356                 IDPropertyTemplate val = {0};
1357                 IDProperty *group;
1358
1359                 val.str= (char*)value;
1360
1361                 group= RNA_struct_idproperties(ptr, 1);
1362                 if(group)
1363                         IDP_AddToGroup(group, IDP_New(IDP_STRING, val, (char*)prop->identifier));
1364         }
1365 }
1366
1367 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
1368 {
1369         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1370         IDProperty *idprop;
1371
1372         if((idprop=rna_idproperty_check(&prop, ptr)))
1373                 return IDP_Int(idprop);
1374         else if(eprop->get)
1375                 return eprop->get(ptr);
1376         else
1377                 return eprop->defaultvalue;
1378 }
1379
1380
1381 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1382 {
1383         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1384         IDProperty *idprop;
1385
1386         if((idprop=rna_idproperty_check(&prop, ptr)))
1387                 IDP_Int(idprop)= value;
1388         else if(eprop->set) {
1389                 eprop->set(ptr, value);
1390         }
1391         else if(prop->flag & PROP_EDITABLE) {
1392                 IDPropertyTemplate val = {0};
1393                 IDProperty *group;
1394
1395                 val.i= value;
1396
1397                 group= RNA_struct_idproperties(ptr, 1);
1398                 if(group)
1399                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1400         }
1401 }
1402
1403 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
1404 {
1405         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1406         IDProperty *idprop;
1407
1408         if((idprop=rna_idproperty_check(&prop, ptr))) {
1409                 pprop= (PointerPropertyRNA*)prop;
1410
1411                 /* for groups, data is idprop itself */
1412                 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
1413         }
1414         else if(pprop->get) {
1415                 return pprop->get(ptr);
1416         }
1417         else if(prop->flag & PROP_IDPROPERTY) {
1418                 /* XXX temporary hack to add it automatically, reading should
1419                    never do any write ops, to ensure thread safety etc .. */
1420                 RNA_property_pointer_add(ptr, prop);
1421                 return RNA_property_pointer_get(ptr, prop);
1422         }
1423         else {
1424                 PointerRNA result;
1425
1426                 memset(&result, 0, sizeof(result));
1427                 return result;
1428         }
1429 }
1430
1431 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
1432 {
1433         IDProperty *idprop;
1434
1435         if((idprop=rna_idproperty_check(&prop, ptr))) {
1436                 /* not supported */
1437         }
1438         else {
1439                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1440
1441                 if(pprop->set && !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL))
1442                         pprop->set(ptr, ptr_value);
1443         }
1444 }
1445
1446 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
1447 {
1448         IDProperty *idprop;
1449
1450         if((idprop=rna_idproperty_check(&prop, ptr))) {
1451                 /* already exists */
1452         }
1453         else if(prop->flag & PROP_IDPROPERTY) {
1454                 IDPropertyTemplate val = {0};
1455                 IDProperty *group;
1456
1457                 val.i= 0;
1458
1459                 group= RNA_struct_idproperties(ptr, 1);
1460                 if(group)
1461                         IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, (char*)prop->identifier));
1462         }
1463         else
1464                 printf("RNA_property_pointer_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1465 }
1466
1467 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
1468 {
1469         IDProperty *idprop, *group;
1470
1471         if((idprop=rna_idproperty_check(&prop, ptr))) {
1472                 group= RNA_struct_idproperties(ptr, 0);
1473                 
1474                 if(group) {
1475                         IDP_RemFromGroup(group, idprop);
1476                         IDP_FreeProperty(idprop);
1477                         MEM_freeN(idprop);
1478                 }
1479         }
1480         else
1481                 printf("RNA_property_pointer_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1482 }
1483
1484 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
1485 {
1486         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1487
1488         iter->ptr.data= rna_iterator_array_get(iter);
1489         iter->ptr.type= cprop->type;
1490         rna_pointer_inherit_id(cprop->type, &iter->parent, &iter->ptr);
1491 }
1492
1493 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
1494 {
1495         IDProperty *idprop;
1496
1497         memset(iter, 0, sizeof(*iter));
1498
1499         if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
1500                 iter->parent= *ptr;
1501                 iter->prop= prop;
1502
1503                 if(idprop)
1504                         rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
1505                 else
1506                         rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
1507
1508                 if(iter->valid)
1509                         rna_property_collection_get_idp(iter);
1510
1511                 iter->idprop= 1;
1512         }
1513         else {
1514                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1515                 cprop->begin(iter, ptr);
1516         }
1517 }
1518
1519 void RNA_property_collection_next(CollectionPropertyIterator *iter)
1520 {
1521         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1522
1523         if(iter->idprop) {
1524                 rna_iterator_array_next(iter);
1525
1526                 if(iter->valid)
1527                         rna_property_collection_get_idp(iter);
1528         }
1529         else
1530                 cprop->next(iter);
1531 }
1532
1533 void RNA_property_collection_end(CollectionPropertyIterator *iter)
1534 {
1535         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1536
1537         if(iter->idprop)
1538                 rna_iterator_array_end(iter);
1539         else
1540                 cprop->end(iter);
1541 }
1542
1543 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
1544 {
1545         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1546         IDProperty *idprop;
1547
1548         if((idprop=rna_idproperty_check(&prop, ptr))) {
1549                 return idprop->len;
1550         }
1551         else if(cprop->length) {
1552                 return cprop->length(ptr);
1553         }
1554         else {
1555                 CollectionPropertyIterator iter;
1556                 int length= 0;
1557
1558                 RNA_property_collection_begin(ptr, prop, &iter);
1559                 for(; iter.valid; RNA_property_collection_next(&iter))
1560                         length++;
1561                 RNA_property_collection_end(&iter);
1562
1563                 return length;
1564         }
1565 }
1566
1567 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
1568 {
1569         IDProperty *idprop;
1570 //      CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1571
1572         if((idprop=rna_idproperty_check(&prop, ptr))) {
1573                 IDPropertyTemplate val = {0};
1574                 IDProperty *item;
1575
1576                 item= IDP_New(IDP_GROUP, val, "");
1577                 IDP_AppendArray(idprop, item);
1578                 IDP_FreeProperty(item);
1579                 MEM_freeN(item);
1580         }
1581         else if(prop->flag & PROP_IDPROPERTY) {
1582                 IDProperty *group, *item;
1583                 IDPropertyTemplate val = {0};
1584
1585                 group= RNA_struct_idproperties(ptr, 1);
1586                 if(group) {
1587                         idprop= IDP_NewIDPArray(prop->identifier);
1588                         IDP_AddToGroup(group, idprop);
1589
1590                         item= IDP_New(IDP_GROUP, val, "");
1591                         IDP_AppendArray(idprop, item);
1592                         IDP_FreeProperty(item);
1593                         MEM_freeN(item);
1594                 }
1595         }
1596
1597         /* py api calls directly */
1598 #if 0
1599         else if(cprop->add){
1600                 if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
1601                         ParameterList params;
1602                         RNA_parameter_list_create(&params, ptr, cprop->add);
1603                         RNA_function_call(NULL, NULL, ptr, cprop->add, &params);
1604                         RNA_parameter_list_free(&params);
1605                 }
1606         }
1607         /*else
1608                 printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);*/
1609 #endif
1610
1611         if(r_ptr) {
1612                 if(idprop) {
1613                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1614
1615                         r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
1616                         r_ptr->type= cprop->type;
1617                         rna_pointer_inherit_id(NULL, ptr, r_ptr);
1618                 }
1619                 else
1620                         memset(r_ptr, 0, sizeof(*r_ptr));
1621         }
1622 }
1623
1624 int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
1625 {
1626         IDProperty *idprop;
1627 //      CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1628
1629         if((idprop=rna_idproperty_check(&prop, ptr))) {
1630                 IDProperty tmp, *array;
1631                 int len;
1632
1633                 len= idprop->len;
1634                 array= IDP_IDPArray(idprop);
1635
1636                 if(key >= 0 && key < len) {
1637                         if(key+1 < len) {
1638                                 /* move element to be removed to the back */
1639                                 memcpy(&tmp, &array[key], sizeof(IDProperty));
1640                                 memmove(array+key, array+key+1, sizeof(IDProperty)*(len-key+1));
1641                                 memcpy(&array[len-1], &tmp, sizeof(IDProperty));
1642                         }
1643
1644                         IDP_ResizeIDPArray(idprop, len-1);
1645                 }
1646
1647                 return 1;
1648         }
1649         else if(prop->flag & PROP_IDPROPERTY)
1650                 return 1;
1651
1652         /* py api calls directly */
1653 #if 0
1654         else if(cprop->remove){
1655                 if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
1656                         ParameterList params;
1657                         RNA_parameter_list_create(&params, ptr, cprop->remove);
1658                         RNA_function_call(NULL, NULL, ptr, cprop->remove, &params);
1659                         RNA_parameter_list_free(&params);
1660                 }
1661
1662                 return 0;
1663         }
1664         /*else
1665                 printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);*/
1666 #endif
1667         return 0;
1668 }
1669
1670 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
1671 {
1672         IDProperty *idprop;
1673
1674         if((idprop=rna_idproperty_check(&prop, ptr)))
1675                 IDP_ResizeIDPArray(idprop, 0);
1676 }
1677
1678 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
1679 {
1680         CollectionPropertyIterator iter;
1681         int index= 0;
1682         
1683         RNA_property_collection_begin(ptr, prop, &iter);
1684         for(index=0; iter.valid; RNA_property_collection_next(&iter), index++) {
1685                 if (iter.ptr.data == t_ptr->data)
1686                         break;
1687         }
1688         RNA_property_collection_end(&iter);
1689         
1690         /* did we find it? */
1691         if (iter.valid)
1692                 return index;
1693         else
1694                 return -1;
1695 }
1696
1697 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
1698 {
1699         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1700
1701         if(cprop->lookupint) {
1702                 /* we have a callback defined, use it */
1703                 *r_ptr= cprop->lookupint(ptr, key);
1704                 return (r_ptr->data != NULL);
1705         }
1706         else {
1707                 /* no callback defined, just iterate and find the nth item */
1708                 CollectionPropertyIterator iter;
1709                 int i;
1710
1711                 RNA_property_collection_begin(ptr, prop, &iter);
1712                 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
1713                         if(i == key) {
1714                                 *r_ptr= iter.ptr;
1715                                 break;
1716                         }
1717                 }
1718                 RNA_property_collection_end(&iter);
1719
1720                 if(!iter.valid)
1721                         memset(r_ptr, 0, sizeof(*r_ptr));
1722
1723                 return iter.valid;
1724         }
1725 }
1726
1727 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
1728 {
1729         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1730
1731         if(cprop->lookupstring) {
1732                 /* we have a callback defined, use it */
1733                 *r_ptr= cprop->lookupstring(ptr, key);
1734                 return (r_ptr->data != NULL);
1735         }
1736         else {
1737                 /* no callback defined, compare with name properties if they exist */
1738                 CollectionPropertyIterator iter;
1739                 PropertyRNA *nameprop;
1740                 char name[256], *nameptr;
1741                 int found= 0;
1742
1743                 RNA_property_collection_begin(ptr, prop, &iter);
1744                 for(; iter.valid; RNA_property_collection_next(&iter)) {
1745                         if(iter.ptr.data && iter.ptr.type->nameproperty) {
1746                                 nameprop= iter.ptr.type->nameproperty;
1747
1748                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
1749
1750                                 if(strcmp(nameptr, key) == 0) {
1751                                         *r_ptr= iter.ptr;
1752                                         found= 1;
1753                                 }
1754
1755                                 if((char *)&name != nameptr)
1756                                         MEM_freeN(nameptr);
1757
1758                                 if(found)
1759                                         break;
1760                         }
1761                 }
1762                 RNA_property_collection_end(&iter);
1763
1764                 if(!iter.valid)
1765                         memset(r_ptr, 0, sizeof(*r_ptr));
1766
1767                 return iter.valid;
1768         }
1769 }
1770
1771 PropertyRNA *RNA_property_collection_active(PropertyRNA *prop)
1772 {
1773         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1774         return cprop->active;
1775 }
1776
1777 FunctionRNA *RNA_property_collection_add_func(PropertyRNA *prop)
1778 {
1779         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1780         return cprop->add;
1781 }
1782
1783 FunctionRNA *RNA_property_collection_remove_func(PropertyRNA *prop)
1784 {
1785         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1786         return cprop->remove;
1787 }
1788
1789 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
1790 {
1791         CollectionPropertyIterator iter;
1792         ArrayIterator *internal;
1793         char *arrayp;
1794
1795         if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
1796                 return 0;
1797
1798         RNA_property_collection_begin(ptr, prop, &iter);
1799
1800         if(iter.valid) {
1801                 /* get data from array iterator and item property */
1802                 internal= iter.internal;
1803                 arrayp= (iter.valid)? iter.ptr.data: NULL;
1804
1805                 if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
1806                         /* we might skip some items, so it's not a proper array */
1807                         RNA_property_collection_end(&iter);
1808                         return 0;
1809                 }
1810
1811                 array->array= arrayp + itemprop->rawoffset;
1812                 array->stride= internal->itemsize;
1813                 array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
1814                 array->type= itemprop->rawtype;
1815         }
1816         else
1817                 memset(array, 0, sizeof(RawArray));
1818
1819         RNA_property_collection_end(&iter);
1820
1821         return 1;
1822 }
1823
1824 #define RAW_GET(dtype, var, raw, a) \
1825 { \
1826         switch(raw.type) { \
1827                 case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
1828                 case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
1829                 case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
1830                 case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
1831                 case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
1832                 default: var = (dtype)0; \
1833         } \
1834 }
1835
1836 #define RAW_SET(dtype, raw, a, var) \
1837 { \
1838         switch(raw.type) { \
1839                 case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
1840                 case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
1841                 case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
1842                 case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
1843                 case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
1844         } \
1845 }
1846
1847 int RNA_raw_type_sizeof(RawPropertyType type)
1848 {
1849         switch(type) {
1850                 case PROP_RAW_CHAR: return sizeof(char);
1851                 case PROP_RAW_SHORT: return sizeof(short);
1852                 case PROP_RAW_INT: return sizeof(int);
1853                 case PROP_RAW_FLOAT: return sizeof(float);
1854                 case PROP_RAW_DOUBLE: return sizeof(double);
1855                 default: return 0;
1856         }
1857 }
1858
1859 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
1860 {
1861         StructRNA *ptype;
1862         PointerRNA itemptr;
1863         PropertyRNA *itemprop, *iprop;
1864         PropertyType itemtype=0;
1865         RawArray in;
1866         int itemlen= 0;
1867
1868         /* initialize in array, stride assumed 0 in following code */
1869         in.array= inarray;
1870         in.type= intype;
1871         in.len= inlen;
1872         in.stride= 0;
1873
1874         ptype= RNA_property_pointer_type(ptr, prop);
1875
1876         /* try to get item property pointer */
1877         RNA_pointer_create(NULL, ptype, NULL, &itemptr);
1878         itemprop= RNA_struct_find_property(&itemptr, propname);
1879
1880         if(itemprop) {
1881                 /* we have item property pointer */
1882                 RawArray out;
1883
1884                 /* check type */
1885                 itemtype= RNA_property_type(itemprop);
1886
1887                 if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
1888                         BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
1889                         return 0;
1890                 }
1891
1892                 /* check item array */
1893                 itemlen= RNA_property_array_length(&itemptr, itemprop);
1894
1895                 /* try to access as raw array */
1896                 if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
1897                         if(in.len != itemlen*out.len) {
1898                                 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*itemlen, in.len);
1899                                 return 0;
1900                         }
1901                         
1902                         /* matching raw types */
1903                         if(out.type == in.type) {
1904                                 void *inp= in.array;
1905                                 void *outp= out.array;
1906                                 int a, size;
1907
1908                                 itemlen= (itemlen == 0)? 1: itemlen;
1909                                 size= RNA_raw_type_sizeof(out.type) * itemlen;
1910
1911                                 for(a=0; a<out.len; a++) {
1912                                         if(set) memcpy(outp, inp, size);
1913                                         else memcpy(inp, outp, size);
1914
1915                                         inp= (char*)inp + size;
1916                                         outp= (char*)outp + out.stride;
1917                                 }
1918
1919                                 return 1;
1920                         }
1921
1922                         /* could also be faster with non-matching types,
1923                          * for now we just do slower loop .. */
1924                 }
1925         }
1926
1927         {
1928                 void *tmparray= NULL;
1929                 int tmplen= 0;
1930                 int err= 0, j, a= 0;
1931
1932                 /* no item property pointer, can still be id property, or
1933                  * property of a type derived from the collection pointer type */
1934                 RNA_PROP_BEGIN(ptr, itemptr, prop) {
1935                         if(itemptr.data) {
1936                                 if(itemprop) {
1937                                         /* we got the property already */
1938                                         iprop= itemprop;
1939                                 }
1940                                 else {
1941                                         /* not yet, look it up and verify if it is valid */
1942                                         iprop= RNA_struct_find_property(&itemptr, propname);
1943
1944                                         if(iprop) {
1945                                                 itemlen= RNA_property_array_length(&itemptr, iprop);
1946                                                 itemtype= RNA_property_type(iprop);
1947                                         }
1948                                         else {
1949                                                 BKE_reportf(reports, RPT_ERROR, "Property named %s not found.", propname);
1950                                                 err= 1;
1951                                                 break;
1952                                         }
1953
1954                                         if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
1955                                                 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
1956                                                 err= 1;
1957                                                 break;
1958                                         }
1959                                 }
1960
1961                                 /* editable check */
1962                                 if(RNA_property_editable(&itemptr, iprop)) {
1963                                         if(a+itemlen > in.len) {
1964                                                 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more).", in.len);
1965                                                 err= 1;
1966                                                 break;
1967                                         }
1968
1969                                         if(itemlen == 0) {
1970                                                 /* handle conversions */
1971                                                 if(set) {
1972                                                         switch(itemtype) {
1973                                                                 case PROP_BOOLEAN: {
1974                                                                         int b;
1975                                                                         RAW_GET(int, b, in, a);
1976                                                                         RNA_property_boolean_set(&itemptr, iprop, b);
1977                                                                         break;
1978                                                                 }
1979                                                                 case PROP_INT: {
1980                                                                         int i;
1981                                                                         RAW_GET(int, i, in, a);
1982                                                                         RNA_property_int_set(&itemptr, iprop, i);
1983                                                                         break;
1984                                                                 }
1985                                                                 case PROP_FLOAT: {
1986                                                                         float f;
1987                                                                         RAW_GET(float, f, in, a);
1988                                                                         RNA_property_float_set(&itemptr, iprop, f);
1989                                                                         break;
1990                                                                 }
1991                                                                 default:
1992                                                                         break;
1993                                                         }
1994                                                 }
1995                                                 else {
1996                                                         switch(itemtype) {
1997                                                                 case PROP_BOOLEAN: {
1998                                                                         int b= RNA_property_boolean_get(&itemptr, iprop);
1999                                                                         RAW_SET(int, in, a, b);
2000                                                                         break;
2001                                                                 }
2002                                                                 case PROP_INT: {
2003                                                                         int i= RNA_property_int_get(&itemptr, iprop);
2004                                                                         RAW_SET(int, in, a, i);
2005                                                                         break;
2006                                                                 }
2007                                                                 case PROP_FLOAT: {
2008                                                                         float f= RNA_property_float_get(&itemptr, iprop);
2009                                                                         RAW_SET(float, in, a, f);
2010                                                                         break;
2011                                                                 }
2012                                                                 default:
2013                                                                         break;
2014                                                         }
2015                                                 }
2016                                                 a++;
2017                                         }
2018                                         else {
2019                                                 /* allocate temporary array if needed */
2020                                                 if(tmparray && tmplen != itemlen) {
2021                                                         MEM_freeN(tmparray);
2022                                                         tmparray= NULL;
2023                                                 }
2024                                                 if(!tmparray) {
2025                                                         tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
2026                                                         tmplen= itemlen;
2027                                                 }
2028
2029                                                 /* handle conversions */
2030                                                 if(set) {
2031                                                         switch(itemtype) {
2032                                                                 case PROP_BOOLEAN: {
2033                                                                         for(j=0; j<itemlen; j++, a++)
2034                                                                                 RAW_GET(int, ((int*)tmparray)[j], in, a);
2035                                                                         RNA_property_boolean_set_array(&itemptr, iprop, tmparray);
2036                                                                         break;
2037                                                                 }
2038                                                                 case PROP_INT: {
2039                                                                         for(j=0; j<itemlen; j++, a++)
2040                                                                                 RAW_GET(int, ((int*)tmparray)[j], in, a);
2041                                                                         RNA_property_int_set_array(&itemptr, iprop, tmparray);
2042                                                                         break;
2043                                                                 }
2044                                                                 case PROP_FLOAT: {
2045                                                                         for(j=0; j<itemlen; j++, a++)
2046                                                                                 RAW_GET(float, ((float*)tmparray)[j], in, a);
2047                                                                         RNA_property_float_set_array(&itemptr, iprop, tmparray);
2048                                                                         break;
2049                                                                 }
2050                                                                 default:
2051                                                                         break;
2052                                                         }
2053                                                 }
2054                                                 else {
2055                                                         switch(itemtype) {
2056                                                                 case PROP_BOOLEAN: {
2057                                                                         RNA_property_boolean_get_array(&itemptr, iprop, tmparray);
2058                                                                         for(j=0; j<itemlen; j++, a++)
2059                                                                                 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2060                                                                         break;
2061                                                                 }
2062                                                                 case PROP_INT: {
2063                                                                         RNA_property_int_get_array(&itemptr, iprop, tmparray);
2064                                                                         for(j=0; j<itemlen; j++, a++)
2065                                                                                 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2066                                                                         break;
2067                                                                 }
2068                                                                 case PROP_FLOAT: {
2069                                                                         RNA_property_float_get_array(&itemptr, iprop, tmparray);
2070                                                                         for(j=0; j<itemlen; j++, a++)
2071                                                                                 RAW_SET(float, in, a, ((float*)tmparray)[j]);
2072                                                                         break;
2073                                                                 }
2074                                                                 default:
2075                                                                         break;
2076                                                         }
2077                                                 }
2078                                         }
2079                                 }
2080                         }
2081                 }
2082                 RNA_PROP_END;
2083
2084                 if(tmparray)
2085                         MEM_freeN(tmparray);
2086
2087                 return !err;
2088         }
2089 }
2090
2091 RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
2092 {
2093         return prop->rawtype;
2094 }
2095
2096 int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
2097 {
2098         return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
2099 }
2100
2101 int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
2102 {
2103         return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
2104 }
2105
2106 /* Standard iterator functions */
2107
2108 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
2109 {
2110         ListBaseIterator *internal;
2111
2112         internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
2113         internal->link= (lb)? lb->first: NULL;
2114         internal->skip= skip;
2115
2116         iter->internal= internal;
2117         iter->valid= (internal->link != NULL);
2118
2119         if(skip && iter->valid && skip(iter, internal->link))
2120                 rna_iterator_listbase_next(iter);
2121 }
2122
2123 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
2124 {
2125         ListBaseIterator *internal= iter->internal;
2126
2127         if(internal->skip) {
2128                 do {
2129                         internal->link= internal->link->next;
2130                         iter->valid= (internal->link != NULL);
2131                 } while(iter->valid && internal->skip(iter, internal->link));
2132         }
2133         else {
2134                 internal->link= internal->link->next;
2135                 iter->valid= (internal->link != NULL);
2136         }
2137 }
2138
2139 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
2140 {
2141         ListBaseIterator *internal= iter->internal;
2142
2143         return internal->link;
2144 }
2145
2146 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
2147 {
2148         MEM_freeN(iter->internal);
2149         iter->internal= NULL;
2150 }
2151
2152 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, int free_ptr, IteratorSkipFunc skip)
2153 {
2154         ArrayIterator *internal;
2155
2156         if(ptr == NULL)
2157                 length= 0;
2158
2159         internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
2160         internal->ptr= ptr;
2161         internal->free_ptr= free_ptr ? ptr:NULL;
2162         internal->endptr= ((char*)ptr)+length*itemsize;
2163         internal->itemsize= itemsize;
2164         internal->skip= skip;
2165
2166         iter->internal= internal;
2167         iter->valid= (internal->ptr != internal->endptr);
2168
2169         if(skip && iter->valid && skip(iter, internal->ptr))
2170                 rna_iterator_array_next(iter);
2171 }
2172
2173 void rna_iterator_array_next(CollectionPropertyIterator *iter)
2174 {
2175         ArrayIterator *internal= iter->internal;
2176
2177         if(internal->skip) {
2178                 do {
2179                         internal->ptr += internal->itemsize;
2180                         iter->valid= (internal->ptr != internal->endptr);
2181                 } while(iter->valid && internal->skip(iter, internal->ptr));
2182         }
2183         else {
2184                 internal->ptr += internal->itemsize;
2185                 iter->valid= (internal->ptr != internal->endptr);
2186         }
2187 }
2188
2189 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
2190 {
2191         ArrayIterator *internal= iter->internal;
2192
2193         return internal->ptr;
2194 }
2195
2196 void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
2197 {
2198         ArrayIterator *internal= iter->internal;
2199
2200         /* for ** arrays */
2201         return *(void**)(internal->ptr);
2202 }
2203
2204 void rna_iterator_array_end(CollectionPropertyIterator *iter)
2205 {
2206         ArrayIterator *internal= iter->internal;
2207         
2208         if(internal->free_ptr) {
2209                 MEM_freeN(internal->free_ptr);
2210                 internal->free_ptr= NULL;
2211         }
2212         MEM_freeN(iter->internal);
2213         iter->internal= NULL;
2214 }
2215
2216 /* RNA Path - Experiment */
2217
2218 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
2219 {
2220         const char *p;
2221         char *buf;
2222         int i, j, len, escape;
2223
2224         len= 0;
2225
2226         if(bracket) {
2227                 /* get data between [], check escaping ] with \] */
2228                 if(**path == '[') (*path)++;
2229                 else return NULL;
2230
2231                 p= *path;
2232
2233                 escape= 0;
2234                 while(*p && (*p != ']' || escape)) {
2235                         escape= (*p == '\\');
2236                         len++;
2237                         p++;
2238                 }
2239
2240                 if(*p != ']') return NULL;
2241         }
2242         else {
2243                 /* get data until . or [ */
2244                 p= *path;
2245
2246                 while(*p && *p != '.' && *p != '[') {
2247                         len++;
2248                         p++;
2249                 }
2250         }
2251         
2252         /* empty, return */
2253         if(len == 0)
2254                 return NULL;
2255         
2256         /* try to use fixed buffer if possible */
2257         if(len+1 < fixedlen)
2258                 buf= fixedbuf;
2259         else
2260                 buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
2261
2262         /* copy string, taking into account escaped ] */
2263         if(bracket) {
2264                 for(p=*path, i=0, j=0; i<len; i++, p++) {
2265                         if(*p == '\\' && *(p+1) == ']');
2266                         else buf[j++]= *p;
2267                 }
2268
2269                 buf[j]= 0;
2270         }
2271         else {
2272                 memcpy(buf, *path, sizeof(char)*len);
2273                 buf[len]= '\0';
2274         }
2275
2276         /* set path to start of next token */
2277         if(*p == ']') p++;
2278         if(*p == '.') p++;
2279         *path= p;
2280
2281         return buf;
2282 }
2283
2284 /* Resolve the given RNA path to find the pointer+property indicated at the end of the path */
2285 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
2286 {
2287         PropertyRNA *prop;
2288         PointerRNA curptr, nextptr;
2289         char fixedbuf[256], *token;
2290         int len, intkey;
2291
2292         prop= NULL;
2293         curptr= *ptr;
2294
2295         if(path==NULL)
2296                 return 0;
2297
2298         while(*path) {
2299                 /* look up property name in current struct */
2300                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
2301
2302                 if(!token)
2303                         return 0;
2304
2305                 prop= RNA_struct_find_property(&curptr, token);
2306
2307                 if(token != fixedbuf)
2308                         MEM_freeN(token);
2309
2310                 if(!prop)
2311                         return 0;
2312
2313                 /* now look up the value of this property if it is a pointer or
2314                  * collection, otherwise return the property rna so that the
2315                  * caller can read the value of the property itself */
2316                 if(RNA_property_type(prop) == PROP_POINTER) {
2317                         nextptr= RNA_property_pointer_get(&curptr, prop);
2318
2319                         if(nextptr.data)
2320                                 curptr= nextptr;
2321                         else
2322                                 return 0;
2323                 }
2324                 else if(RNA_property_type(prop) == PROP_COLLECTION && *path) {
2325                         /* resolve the lookup with [] brackets */
2326                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
2327
2328                         if(!token)
2329                                 return 0;
2330
2331                         len= strlen(token);
2332                         
2333                         /* check for "" to see if it is a string */
2334                         if(len >= 2 && token[0] == '"' && token[len-1] == '"') {
2335                                 /* strip away "" */
2336                                 token[len-1]= 0;
2337                                 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
2338                         }
2339                         else {
2340                                 /* otherwise do int lookup */
2341                                 intkey= atoi(token);
2342                                 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
2343                         }
2344
2345                         if(token != fixedbuf)
2346                                 MEM_freeN(token);
2347
2348                         if(nextptr.data)
2349                                 curptr= nextptr;
2350                         else
2351                                 return 0;
2352                 }
2353         }
2354
2355         *r_ptr= curptr;
2356         *r_prop= prop;
2357
2358         return 1;
2359 }
2360
2361 char *RNA_path_append(const char *path, PointerRNA *ptr, PropertyRNA *prop, int intkey, const char *strkey)
2362 {
2363         DynStr *dynstr;
2364         const char *s;
2365         char appendstr[128], *result;
2366         
2367         dynstr= BLI_dynstr_new();
2368
2369         /* add .identifier */
2370         if(path) {
2371                 BLI_dynstr_append(dynstr, (char*)path);
2372                 if(*path)
2373                         BLI_dynstr_append(dynstr, ".");
2374         }
2375
2376         BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(prop));
2377
2378         if(RNA_property_type(prop) == PROP_COLLECTION) {
2379                 /* add ["strkey"] or [intkey] */
2380                 BLI_dynstr_append(dynstr, "[");
2381
2382                 if(strkey) {
2383                         BLI_dynstr_append(dynstr, "\"");
2384                         for(s=strkey; *s; s++) {
2385                                 if(*s == '[') {
2386                                         appendstr[0]= '\\';
2387                                         appendstr[1]= *s;
2388                                         appendstr[2]= 0;
2389                                 }
2390                                 else {
2391                                         appendstr[0]= *s;
2392                                         appendstr[1]= 0;
2393                                 }
2394                                 BLI_dynstr_append(dynstr, appendstr);
2395                         }
2396                         BLI_dynstr_append(dynstr, "\"");
2397                 }
2398                 else {
2399                         sprintf(appendstr, "%d", intkey);
2400                         BLI_dynstr_append(dynstr, appendstr);
2401                 }
2402
2403                 BLI_dynstr_append(dynstr, "]");
2404         }
2405
2406         result= BLI_dynstr_get_cstring(dynstr);
2407         BLI_dynstr_free(dynstr);
2408
2409         return result;
2410 }
2411
2412 char *RNA_path_back(const char *path)
2413 {
2414         char fixedbuf[256];
2415         const char *previous, *current;
2416         char *result, *token;
2417         int i;
2418
2419         if(!path)
2420                 return NULL;
2421
2422         previous= NULL;
2423         current= path;
2424
2425         /* parse token by token until the end, then we back up to the previous
2426          * position and strip of the next token to get the path one step back */
2427         while(*current) {
2428                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
2429
2430                 if(!token)
2431                         return NULL;
2432                 if(token != fixedbuf)
2433                         MEM_freeN(token);
2434
2435                 /* in case of collection we also need to strip off [] */
2436                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
2437                 if(token && token != fixedbuf)
2438                         MEM_freeN(token);
2439                 
2440                 if(!*current)
2441                         break;
2442
2443                 previous= current;
2444         }
2445
2446         if(!previous)
2447                 return NULL;
2448
2449         /* copy and strip off last token */
2450         i= previous - path;
2451         result= BLI_strdup(path);
2452
2453         if(i > 0 && result[i-1] == '.') i--;
2454         result[i]= 0;
2455
2456         return result;
2457 }
2458
2459 char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
2460 {
2461         char *ptrpath=NULL;
2462
2463         if(!ptr->id.data || !ptr->data)
2464                 return NULL;
2465         
2466         if(!RNA_struct_is_ID(ptr->type)) {
2467                 if(ptr->type->path) {
2468                         /* if type has a path to some ID, use it */
2469                         ptrpath= ptr->type->path(ptr);
2470                 }
2471                 else if(ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
2472                         PointerRNA parentptr;
2473                         PropertyRNA *userprop;
2474                         
2475                         /* find the property in the struct we're nested in that references this struct, and 
2476                          * use its identifier as the first part of the path used...
2477                          */
2478                         RNA_id_pointer_create(ptr->id.data, &parentptr);
2479                         userprop= RNA_struct_find_nested(&parentptr, ptr->type); 
2480                         
2481                         if(userprop)
2482                                 ptrpath= BLI_strdup(RNA_property_identifier(userprop));
2483                         else
2484                                 return NULL; // can't do anything about this case yet...
2485                 }
2486                 else
2487                         return NULL;
2488         }
2489         
2490         return ptrpath;
2491 }
2492
2493 char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
2494 {
2495         const char *propname;
2496         char *ptrpath, *path;
2497
2498         if(!ptr->id.data || !ptr->data || !prop)
2499                 return NULL;
2500         
2501         /* path from ID to the struct holding this property */
2502         ptrpath= RNA_path_from_ID_to_struct(ptr);
2503
2504         propname= RNA_property_identifier(prop);
2505
2506         if(ptrpath) {
2507                 path= BLI_sprintfN("%s.%s", ptrpath, propname);
2508                 MEM_freeN(ptrpath);
2509         }
2510         else
2511                 path= BLI_strdup(propname);
2512         
2513         return path;
2514 }
2515
2516 /* Quick name based property access */
2517
2518 int RNA_boolean_get(PointerRNA *ptr, const char *name)
2519 {
2520         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2521
2522         if(prop) {
2523                 return RNA_property_boolean_get(ptr, prop);
2524         }
2525         else {
2526                 printf("RNA_boolean_get: %s.%s not found.\n", ptr->type->identifier, name);
2527                 return 0;
2528         }
2529 }
2530
2531 void RNA_boolean_set(PointerRNA *ptr, const char *name, int value)
2532 {
2533         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2534
2535         if(prop)
2536                 RNA_property_boolean_set(ptr, prop, value);
2537         else
2538                 printf("RNA_boolean_set: %s.%s not found.\n", ptr->type->identifier, name);
2539 }
2540
2541 void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values)
2542 {
2543         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2544
2545         if(prop)
2546                 RNA_property_boolean_get_array(ptr, prop, values);
2547         else
2548                 printf("RNA_boolean_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2549 }
2550
2551 void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values)
2552 {
2553         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2554
2555         if(prop)
2556                 RNA_property_boolean_set_array(ptr, prop, values);
2557         else
2558                 printf("RNA_boolean_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2559 }
2560
2561 int RNA_int_get(PointerRNA *ptr, const char *name)
2562 {
2563         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2564
2565         if(prop) {
2566                 return RNA_property_int_get(ptr, prop);
2567         }
2568         else {
2569                 printf("RNA_int_get: %s.%s not found.\n", ptr->type->identifier, name);
2570                 return 0;
2571         }
2572 }
2573
2574 void RNA_int_set(PointerRNA *ptr, const char *name, int value)
2575 {
2576         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2577
2578         if(prop)
2579                 RNA_property_int_set(ptr, prop, value);
2580         else
2581                 printf("RNA_int_set: %s.%s not found.\n", ptr->type->identifier, name);
2582 }
2583
2584 void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
2585 {
2586         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2587
2588         if(prop)
2589                 RNA_property_int_get_array(ptr, prop, values);
2590         else
2591                 printf("RNA_int_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2592 }
2593
2594 void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
2595 {
2596         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2597
2598         if(prop)
2599                 RNA_property_int_set_array(ptr, prop, values);
2600         else
2601                 printf("RNA_int_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2602 }
2603
2604 float RNA_float_get(PointerRNA *ptr, const char *name)
2605 {
2606         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2607
2608         if(prop) {
2609                 return RNA_property_float_get(ptr, prop);
2610         }
2611         else {
2612                 printf("RNA_float_get: %s.%s not found.\n", ptr->type->identifier, name);
2613                 return 0;
2614         }
2615 }
2616
2617 void RNA_float_set(PointerRNA *ptr, const char *name, float value)
2618 {
2619         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2620
2621         if(prop)
2622                 RNA_property_float_set(ptr, prop, value);
2623         else
2624                 printf("RNA_float_set: %s.%s not found.\n", ptr->type->identifier, name);
2625 }
2626
2627 void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
2628 {
2629         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2630
2631         if(prop)
2632                 RNA_property_float_get_array(ptr, prop, values);
2633         else
2634                 printf("RNA_float_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2635 }
2636
2637 void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
2638 {
2639         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2640
2641         if(prop)
2642                 RNA_property_float_set_array(ptr, prop, values);
2643         else
2644                 printf("RNA_float_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2645 }
2646
2647 int RNA_enum_get(PointerRNA *ptr, const char *name)
2648 {
2649         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2650
2651         if(prop) {
2652                 return RNA_property_enum_get(ptr, prop);
2653         }
2654         else {
2655                 printf("RNA_enum_get: %s.%s not found.\n", ptr->type->identifier, name);
2656                 return 0;
2657         }
2658 }
2659
2660 void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
2661 {
2662         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2663
2664         if(prop)
2665                 RNA_property_enum_set(ptr, prop, value);
2666         else
2667                 printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
2668 }
2669
2670 int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
2671 {
2672         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2673         EnumPropertyItem *item;
2674         int free;
2675
2676         if(prop) {
2677                 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
2678
2679                 for(; item->identifier; item++)
2680                         if(strcmp(item->identifier, enumname) == 0)
2681                                 return (item->value == RNA_property_enum_get(ptr, prop));
2682
2683                 if(free)
2684                         MEM_freeN(item);
2685
2686                 printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname);
2687                 return 0;
2688         }
2689         else {
2690                 printf("RNA_enum_is_equal: %s.%s not found.\n", ptr->type->identifier, name);
2691                 return 0;
2692         }
2693 }
2694
2695 int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value)
2696 {
2697         for( ; item->identifier; item++) {
2698                 if(strcmp(item->identifier, identifier)==0) {
2699                         *value= item->value;
2700                         return 1;
2701                 }
2702         }
2703         
2704         return 0;
2705 }
2706
2707 int     RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier)
2708 {
2709         for( ; item->identifier; item++) {
2710                 if(item->value==value) {
2711                         *identifier= item->identifier;
2712                         return 1;
2713                 }
2714         }
2715
2716         return 0;
2717 }
2718
2719
2720
2721 void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
2722 {
2723         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2724
2725         if(prop)
2726                 RNA_property_string_get(ptr, prop, value);
2727         else
2728                 printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name);
2729 }
2730
2731 char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
2732 {
2733         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2734
2735         if(prop) {
2736                 return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen);
2737         }
2738         else {
2739                 printf("RNA_string_get_alloc: %s.%s not found.\n", ptr->type->identifier, name);
2740                 return 0;
2741         }
2742 }
2743
2744 int RNA_string_length(PointerRNA *ptr, const char *name)
2745 {
2746         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2747
2748         if(prop) {
2749                 return RNA_property_string_length(ptr, prop);
2750         }
2751         else {
2752                 printf("RNA_string_length: %s.%s not found.\n", ptr->type->identifier, name);
2753                 return 0;
2754         }
2755 }
2756
2757 void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
2758 {
2759         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2760
2761         if(prop)
2762                 RNA_property_string_set(ptr, prop, value);
2763         else
2764                 printf("RNA_string_set: %s.%s not found.\n", ptr->type->identifier, name);
2765 }
2766
2767 PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
2768 {
2769         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2770
2771         if(prop) {
2772                 return RNA_property_pointer_get(ptr, prop);
2773         }
2774         else {
2775                 PointerRNA result;
2776
2777                 printf("RNA_pointer_get: %s.%s not found.\n", ptr->type->identifier, name);
2778
2779                 memset(&result, 0, sizeof(result));
2780                 return result;
2781         }
2782 }
2783
2784 void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
2785 {
2786         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2787
2788         if(prop) {
2789                 RNA_property_pointer_set(ptr, prop, ptr_value);
2790         }
2791         else {
2792                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
2793         }
2794 }
2795
2796 void RNA_pointer_add(PointerRNA *ptr, const char *name)
2797 {
2798         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2799
2800         if(prop)
2801                 RNA_property_pointer_add(ptr, prop);
2802         else
2803                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
2804 }
2805
2806 void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter)
2807 {
2808         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2809
2810         if(prop)
2811                 RNA_property_collection_begin(ptr, prop, iter);
2812         else
2813                 printf("RNA_collection_begin: %s.%s not found.\n", ptr->type->identifier, name);
2814 }
2815
2816 void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
2817 {
2818         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2819
2820         if(prop)
2821                 RNA_property_collection_add(ptr, prop, r_value);
2822         else
2823                 printf("RNA_collection_add: %s.%s not found.\n", ptr->type->identifier, name);
2824 }
2825
2826 void RNA_collection_clear(PointerRNA *ptr, const char *name)
2827 {
2828         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2829
2830         if(prop)
2831                 RNA_property_collection_clear(ptr, prop);
2832         else
2833                 printf("RNA_collection_clear: %s.%s not found.\n", ptr->type->identifier, name);
2834 }
2835
2836 int RNA_collection_length(PointerRNA *ptr, const char *name)
2837 {
2838         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2839
2840         if(prop) {
2841                 return RNA_property_collection_length(ptr, prop);
2842         }
2843         else {
2844                 printf("RNA_collection_length: %s.%s not found.\n", ptr->type->identifier, name);
2845                 return 0;
2846         }
2847 }
2848
2849 int RNA_property_is_set(PointerRNA *ptr, const char *name)
2850 {
2851         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2852
2853         if(prop) {
2854                 if(prop->flag & PROP_IDPROPERTY)
2855                         return (rna_idproperty_find(ptr, name) != NULL);
2856                 else
2857                         return 1;
2858         }
2859         else {
2860                 // printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name);
2861                 return 0;
2862         }
2863 }
2864
2865 /* string representation of a property, python
2866  * compatible but can be used for display too*/
2867 char *RNA_pointer_as_string(PointerRNA *ptr)
2868 {
2869         DynStr *dynstr= BLI_dynstr_new();
2870         char *cstring;
2871         
2872         const char *propname;
2873         int first_time = 1;
2874         
2875         BLI_dynstr_append(dynstr, "{");
2876         
2877         RNA_STRUCT_BEGIN(ptr, prop) {
2878                 propname = RNA_property_identifier(prop);
2879                 
2880                 if(strcmp(propname, "rna_type")==0)
2881                         continue;
2882                 
2883                 if(first_time==0)
2884                         BLI_dynstr_append(dynstr, ", ");
2885                 first_time= 0;
2886                 
2887                 cstring = RNA_property_as_string(NULL, ptr, prop);
2888                 BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
2889                 MEM_freeN(cstring);
2890         }
2891         RNA_STRUCT_END;
2892
2893         BLI_dynstr_append(dynstr, "}"); 
2894         
2895         
2896         cstring = BLI_dynstr_get_cstring(dynstr);
2897         BLI_dynstr_free(dynstr);
2898         return cstring;
2899 }
2900
2901 char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
2902 {
2903         int type = RNA_property_type(prop);
2904         int len = RNA_property_array_length(ptr, prop);
2905         int i;
2906
2907         DynStr *dynstr= BLI_dynstr_new();
2908         char *cstring;
2909         
2910
2911         /* see if we can coorce into a python type - PropertyType */
2912         switch (type) {
2913         case PROP_BOOLEAN:
2914                 if(len==0) {
2915                         BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
2916                 }
2917                 else {
2918                         BLI_dynstr_append(dynstr, "(");
2919                         for(i=0; i<len; i++) {
2920                                 BLI_dynstr_appendf(dynstr, i?", %s":"%s", RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False");
2921                         }
2922                         if(len==1)
2923                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2924                         BLI_dynstr_append(dynstr, ")");
2925                 }
2926                 break;
2927         case PROP_INT:
2928                 if(len==0) {
2929                         BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
2930                 }
2931                 else {
2932                         BLI_dynstr_append(dynstr, "(");
2933                         for(i=0; i<len; i++) {
2934                                 BLI_dynstr_appendf(dynstr, i?", %d":"%d", RNA_property_int_get_index(ptr, prop, i));
2935                         }
2936                         if(len==1)
2937                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2938                         BLI_dynstr_append(dynstr, ")");
2939                 }
2940                 break;
2941         case PROP_FLOAT:
2942                 if(len==0) {
2943                         BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
2944                 }
2945                 else {
2946                         BLI_dynstr_append(dynstr, "(");
2947                         for(i=0; i<len; i++) {
2948                                 BLI_dynstr_appendf(dynstr, i?", %g":"%g", RNA_property_float_get_index(ptr, prop, i));
2949                         }
2950                         if(len==1)
2951                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2952                         BLI_dynstr_append(dynstr, ")");
2953                 }
2954                 break;
2955         case PROP_STRING:
2956         {
2957                 /* string arrays dont exist */
2958                 char *buf;
2959                 buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
2960                 BLI_dynstr_appendf(dynstr, "\"%s\"", buf);
2961                 MEM_freeN(buf);
2962                 break;
2963         }
2964         case PROP_ENUM:
2965         {
2966                 /* string arrays dont exist */
2967                 const char *identifier;
2968                 int val = RNA_property_enum_get(ptr, prop);
2969
2970                 if(RNA_property_enum_identifier(C, ptr, prop, val, &identifier)) {
2971                         BLI_dynstr_appendf(dynstr, "'%s'", identifier);
2972                 }
2973                 else {
2974                         BLI_dynstr_appendf(dynstr, "'<UNKNOWN ENUM>'", identifier);
2975                 }
2976                 break;
2977         }
2978         case PROP_POINTER:
2979         {
2980                 BLI_dynstr_append(dynstr, "'<POINTER>'"); /* TODO */
2981                 break;
2982         }
2983         case PROP_COLLECTION:
2984         {
2985                 int first_time = 1;
2986                 CollectionPropertyIterator collect_iter;
2987                 BLI_dynstr_append(dynstr, "[");
2988                 
2989                 for(RNA_property_collection_begin(ptr, prop, &collect_iter); collect_iter.valid; RNA_property_collection_next(&collect_iter)) {
2990                         PointerRNA itemptr= collect_iter.ptr;
2991                         
2992                         if(first_time==0)
2993                                 BLI_dynstr_append(dynstr, ", ");
2994                         first_time= 0;
2995                         
2996                         /* now get every prop of the collection */
2997                         cstring= RNA_pointer_as_string(&itemptr);
2998                         BLI_dynstr_append(dynstr, cstring);
2999                         MEM_freeN(cstring);
3000                 }
3001                 
3002                 RNA_property_collection_end(&collect_iter);
3003                 BLI_dynstr_append(dynstr, "]");
3004                 break;
3005         }
3006         default:
3007                 BLI_dynstr_append(dynstr, "'<UNKNOWN TYPE>'"); /* TODO */
3008                 break;
3009         }
3010
3011         cstring = BLI_dynstr_get_cstring(dynstr);
3012         BLI_dynstr_free(dynstr);
3013         return cstring;
3014 }
3015
3016 /* Function */
3017
3018 const char *RNA_function_identifier(FunctionRNA *func)
3019 {
3020         return func->identifier;
3021 }
3022
3023 PropertyRNA *RNA_function_return(FunctionRNA *func)
3024 {
3025         return func->ret;
3026 }
3027
3028 const char *RNA_function_ui_description(FunctionRNA *func)
3029 {
3030         return func->description;
3031 }
3032
3033 int RNA_function_flag(FunctionRNA *func)
3034 {
3035         return func->flag;
3036 }
3037
3038 PropertyRNA *RNA_function_get_parameter(PointerRNA *ptr, FunctionRNA *func, int index)
3039 {
3040         PropertyRNA *parm;
3041         int i;
3042
3043         parm= func->cont.properties.first;
3044         for(i= 0; parm; parm= parm->next, i++)
3045                 if(i==index)
3046                         return parm;
3047
3048         return NULL;
3049 }
3050
3051 PropertyRNA *RNA_function_find_parameter(PointerRNA *ptr, FunctionRNA *func, const char *identifier)
3052 {
3053         PropertyRNA *parm;
3054
3055         parm= func->cont.properties.first;
3056         for(; parm; parm= parm->next)
3057                 if(strcmp(parm->identifier, identifier)==0)
3058                         return parm;
3059
3060         return NULL;
3061 }
3062
3063 const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func)
3064 {
3065         return &func->cont.properties;
3066 }
3067
3068 /* Utility */
3069
3070 ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, FunctionRNA *func)
3071 {
3072         PropertyRNA *parm;
3073         void *data;
3074         int tot= 0, size;
3075
3076         /* allocate data */
3077         for(parm= func->cont.properties.first; parm; parm= parm->next)
3078                 tot+= rna_parameter_size(parm);
3079
3080         parms->data= MEM_callocN(tot, "RNA_parameter_list_create");
3081         parms->func= func;
3082         parms->tot= tot;
3083
3084         /* set default values */
3085         data= parms->data;
3086
3087         for(parm= func->cont.properties.first; parm; parm= parm->next) {
3088                 size= rna_parameter_size(parm);
3089
3090                 if(!(parm->flag & PROP_REQUIRED)) {
3091                         switch(parm->type) {
3092                                 case PROP_BOOLEAN:
3093                                         if(parm->arraydimension) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size);
3094                                         else memcpy(data, &((BooleanPropertyRNA*)parm)->defaultvalue, size);
3095                                         break;
3096                                 case PROP_INT:
3097                                         if(parm->arraydimension) memcpy(data, &((IntPropertyRNA*)parm)->defaultarray, size);
3098                                         else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size);
3099                                         break;
3100                                 case PROP_FLOAT:
3101                                         if(parm->arraydimension) memcpy(data, &((FloatPropertyRNA*)parm)->defaultarray, size);
3102                                         else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size);
3103                                         break;
3104                                 case PROP_ENUM:
3105                                         memcpy(data, &((EnumPropertyRNA*)parm)->defaultvalue, size);
3106                                         break;
3107                                 case PROP_STRING: {
3108                                         const char *defvalue= ((StringPropertyRNA*)parm)->defaultvalue;
3109                                         if(defvalue && defvalue[0])
3110                                                 memcpy(data, &defvalue, size);
3111                                         break;
3112                                 }
3113                                 case PROP_POINTER:
3114                                 case PROP_COLLECTION:
3115                                         break;
3116                         }
3117                 }
3118
3119                 data= ((char*)data) + size;
3120         }
3121
3122         return parms;
3123 }
3124
3125 void RNA_parameter_list_free(ParameterList *parms)
3126 {
3127         PropertyRNA *parm;
3128         int tot;
3129
3130         parm= parms->func->cont.properties.first;
3131         for(tot= 0; parm; parm= parm->next) {
3132                 if(parm->type == PROP_COLLECTION)
3133                         BLI_freelistN((ListBase*)((char*)parms->data+tot));
3134                 else if (parm->flag & PROP_DYNAMIC) {
3135                         /* for dynamic arrays and strings, data is a pointer to an array */
3136                         char *array= *(char**)((char*)parms->data+tot);
3137                         if(array)
3138                                 MEM_freeN(array);
3139                 }
3140
3141                 tot+= rna_parameter_size(parm);
3142         }
3143
3144         MEM_freeN(parms->data);
3145         parms->data= NULL;
3146
3147         parms->func= NULL;
3148 }
3149
3150 int  RNA_parameter_list_size(ParameterList *parms)
3151 {
3152         return parms->tot;
3153 }
3154
3155 void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
3156 {
3157         PropertyType ptype;
3158
3159         RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr);
3160
3161         iter->parms= parms;
3162         iter->parm= parms->func->cont.properties.first;
3163         iter->valid= iter->parm != NULL;
3164         iter->offset= 0;
3165
3166         if(iter->valid) {
3167                 iter->size= rna_parameter_size(iter->parm);
3168                 iter->data= (((char*)iter->parms->data)+iter->offset);
3169                 ptype= RNA_property_type(iter->parm);
3170         }
3171 }
3172
3173 void RNA_parameter_list_next(ParameterIterator *iter)
3174 {
3175         PropertyType ptype;
3176
3177         iter->offset+= iter->size;
3178         iter->parm= iter->parm->next;
3179         iter->valid= iter->parm != NULL;
3180
3181         if(iter->valid) {
3182                 iter->size= rna_parameter_size(iter->parm);
3183                 iter->data= (((char*)iter->parms->data)+iter->offset);
3184                 ptype= RNA_property_type(iter->parm);
3185         }
3186 }
3187
3188 void RNA_parameter_list_end(ParameterIterator *iter)
3189 {
3190         /* nothing to do */
3191 }
3192
3193 void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value)
3194 {
3195         ParameterIterator iter;
3196
3197         RNA_parameter_list_begin(parms, &iter);
3198
3199         for(; iter.valid; RNA_parameter_list_next(&iter))
3200                 if(iter.parm==parm) 
3201                         break;
3202
3203         if(iter.valid)
3204                 *value= iter.data;
3205         else
3206                 *value= NULL;
3207
3208         RNA_parameter_list_end(&iter);
3209 }
3210
3211 void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value)
3212 {
3213         PropertyRNA *parm;
3214
3215         parm= parms->func->cont.properties.first;
3216         for(; parm; parm= parm->next)
3217                 if(strcmp(RNA_property_identifier(parm), identifier)==0)
3218                         break;
3219
3220         if(parm)
3221                 RNA_parameter_get(parms, parm, value);
3222 }
3223
3224 void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value)
3225 {
3226         ParameterIterator iter;
3227
3228         RNA_parameter_list_begin(parms, &iter);
3229
3230         for(; iter.valid; RNA_parameter_list_next(&iter))
3231                 if(iter.parm==parm) 
3232                         break;
3233
3234         if(iter.valid)
3235                 memcpy(iter.data, value, iter.size);
3236
3237         RNA_parameter_list_end(&iter);
3238 }
3239
3240 void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void *value)
3241 {
3242         PropertyRNA *parm;
3243
3244         parm= parms->func->cont.properties.first;
3245         for(; parm; parm= parm->next)
3246                 if(strcmp(RNA_property_identifier(parm), identifier)==0)
3247                         break;
3248
3249         if(parm)
3250                 RNA_parameter_set(parms, parm, value);
3251 }
3252
3253 int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
3254 {
3255         if(func->call) {
3256                 func->call(C, reports, ptr, parms);
3257
3258                 return 0;
3259         }
3260
3261         return -1;
3262 }
3263
3264 int RNA_function_call_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms)
3265 {
3266         FunctionRNA *func;
3267
3268         func= RNA_struct_find_function(ptr, identifier);
3269
3270         if(func)
3271                 return RNA_function_call(C, reports, ptr, func, parms);
3272
3273         return -1;
3274 }
3275
3276 int RNA_function_call_direct(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, ...)
3277 {
3278         va_list args;
3279         int ret;
3280
3281         va_start(args, format);
3282
3283         ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);
3284
3285         va_end(args);
3286
3287         return ret;
3288 }
3289
3290 int RNA_function_call_direct_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, ...)
3291 {
3292         FunctionRNA *func;
3293
3294         func= RNA_struct_find_function(ptr, identifier);
3295
3296         if(func) {
3297                 va_list args;
3298                 int ret;
3299
3300                 va_start(args, format);
3301
3302                 ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);