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