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