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