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