Darn editmesh code! Trying to prevent user error (add overlapping faces)
[blender-staging.git] / source / blender / python / api2_2x / Lamp.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Nathan Letwory, Stephen Swaney,
29  * Ken Hughes
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 */
33
34 #include "Lamp.h" /*This must come first*/
35
36 #include "BKE_main.h"
37 #include "BKE_global.h"
38 #include "BKE_object.h"
39 #include "BKE_library.h"
40 #include "BLI_blenlib.h"
41 #include "BIF_space.h"
42 #include "BSE_editipo.h"
43 #include "mydevice.h"
44 #include "Ipo.h"
45 #include "constant.h"
46 #include "gen_utils.h"
47
48 /*****************************************************************************/
49 /* Python BPy_Lamp defaults:                                                 */
50 /*****************************************************************************/
51
52 /* Lamp types */
53
54 /* NOTE:
55  these are the same values as LA_* from DNA_lamp_types.h
56  is there some reason we are not simply using those #defines?
57  s. swaney 8-oct-2004
58 */
59
60 #define EXPP_LAMP_TYPE_LAMP 0
61 #define EXPP_LAMP_TYPE_SUN  1
62 #define EXPP_LAMP_TYPE_SPOT 2
63 #define EXPP_LAMP_TYPE_HEMI 3
64 #define EXPP_LAMP_TYPE_AREA 4
65 #define EXPP_LAMP_TYPE_YF_PHOTON 5
66 /*
67   define a constant to keep magic numbers out of the code
68   this value should be equal to the last EXPP_LAMP_TYPE_*
69 */
70 #define EXPP_LAMP_TYPE_MAX  5
71
72 /* Lamp mode flags */
73
74 #define EXPP_LAMP_MODE_SHADOWS       1
75 #define EXPP_LAMP_MODE_HALO          2
76 #define EXPP_LAMP_MODE_LAYER         4
77 #define EXPP_LAMP_MODE_QUAD          8
78 #define EXPP_LAMP_MODE_NEGATIVE     16
79 #define EXPP_LAMP_MODE_ONLYSHADOW   32
80 #define EXPP_LAMP_MODE_SPHERE       64
81 #define EXPP_LAMP_MODE_SQUARE      128
82 #define EXPP_LAMP_MODE_TEXTURE     256
83 #define EXPP_LAMP_MODE_OSATEX      512
84 #define EXPP_LAMP_MODE_DEEPSHADOW 1024
85 #define EXPP_LAMP_MODE_NODIFFUSE  2048
86 #define EXPP_LAMP_MODE_NOSPECULAR 4096
87 /* Lamp MIN, MAX values */
88
89 #define EXPP_LAMP_SAMPLES_MIN 1
90 #define EXPP_LAMP_SAMPLES_MAX 16
91 #define EXPP_LAMP_BUFFERSIZE_MIN 512
92 #define EXPP_LAMP_BUFFERSIZE_MAX 5120
93 #define EXPP_LAMP_ENERGY_MIN  0.0
94 #define EXPP_LAMP_ENERGY_MAX 10.0
95 #define EXPP_LAMP_DIST_MIN    0.1f
96 #define EXPP_LAMP_DIST_MAX 5000.0
97 #define EXPP_LAMP_SPOTSIZE_MIN   1.0
98 #define EXPP_LAMP_SPOTSIZE_MAX 180.0
99 #define EXPP_LAMP_SPOTBLEND_MIN 0.00
100 #define EXPP_LAMP_SPOTBLEND_MAX 1.00
101 #define EXPP_LAMP_CLIPSTART_MIN    0.1f
102 #define EXPP_LAMP_CLIPSTART_MAX 1000.0
103 #define EXPP_LAMP_CLIPEND_MIN    1.0
104 #define EXPP_LAMP_CLIPEND_MAX 5000.0
105 #define EXPP_LAMP_BIAS_MIN 0.01f
106 #define EXPP_LAMP_BIAS_MAX 5.00
107 #define EXPP_LAMP_SOFTNESS_MIN   1.0
108 #define EXPP_LAMP_SOFTNESS_MAX 100.0
109 #define EXPP_LAMP_HALOINT_MIN 0.0
110 #define EXPP_LAMP_HALOINT_MAX 5.0
111 #define EXPP_LAMP_HALOSTEP_MIN  0
112 #define EXPP_LAMP_HALOSTEP_MAX 12
113 #define EXPP_LAMP_QUAD1_MIN 0.0
114 #define EXPP_LAMP_QUAD1_MAX 1.0
115 #define EXPP_LAMP_QUAD2_MIN 0.0
116 #define EXPP_LAMP_QUAD2_MAX 1.0
117 #define EXPP_LAMP_COL_MIN 0.0
118 #define EXPP_LAMP_COL_MAX 1.0
119
120 /* Lamp_setComponent() keys for which color to get/set */
121 #define EXPP_LAMP_COMP_R                        0x00
122 #define EXPP_LAMP_COMP_G                        0x01
123 #define EXPP_LAMP_COMP_B                        0x02
124
125 #define IPOKEY_RGB       0
126 #define IPOKEY_ENERGY    1
127 #define IPOKEY_SPOTSIZE  2
128 #define IPOKEY_OFFSET    3
129 #define IPOKEY_SIZE      4
130
131 /*****************************************************************************/
132 /* Python API function prototypes for the Lamp module.                       */
133 /*****************************************************************************/
134 static PyObject *M_Lamp_New( PyObject * self, PyObject * args,
135                              PyObject * keywords );
136 static PyObject *M_Lamp_Get( PyObject * self, PyObject * args );
137
138 /*****************************************************************************/
139 /* The following string definitions are used for documentation strings.      */
140 /* In Python these will be written to the console when doing a               */
141 /* Blender.Lamp.__doc__                                                      */
142 /*****************************************************************************/
143 static char M_Lamp_doc[] = "The Blender Lamp module\n\n\
144 This module provides control over **Lamp Data** objects in Blender.\n\n\
145 Example::\n\n\
146   from Blender import Lamp\n\
147   l = Lamp.New('Spot')            # create new 'Spot' lamp data\n\
148   l.setMode('square', 'shadow')   # set these two lamp mode flags\n\
149   ob = Object.New('Lamp')         # create new lamp object\n\
150   ob.link(l)                      # link lamp obj with lamp data\n";
151
152 static char M_Lamp_New_doc[] = "Lamp.New (type = 'Lamp', name = 'LampData'):\n\
153         Return a new Lamp Data object with the given type and name.";
154
155 static char M_Lamp_Get_doc[] = "Lamp.Get (name = None):\n\
156         Return the Lamp Data with the given name, None if not found, or\n\
157         Return a list with all Lamp Data objects in the current scene,\n\
158         if no argument was given.";
159
160 /*****************************************************************************/
161 /* Python method structure definition for Blender.Lamp module:               */
162 /*****************************************************************************/
163 struct PyMethodDef M_Lamp_methods[] = {
164         {"New", ( PyCFunction ) M_Lamp_New, METH_VARARGS | METH_KEYWORDS,
165          M_Lamp_New_doc},
166         {"Get", M_Lamp_Get, METH_VARARGS, M_Lamp_Get_doc},
167         {"get", M_Lamp_Get, METH_VARARGS, M_Lamp_Get_doc},
168         {NULL, NULL, 0, NULL}
169 };
170
171 /*****************************************************************************/
172 /* Python BPy_Lamp methods declarations:                                     */
173 /*****************************************************************************/
174 static PyObject *Lamp_getName( BPy_Lamp * self );
175 static PyObject *Lamp_getType( BPy_Lamp * self );
176 static PyObject *Lamp_getTypesConst( void );
177 static PyObject *Lamp_getMode( BPy_Lamp * self );
178 static PyObject *Lamp_getModesConst( void );
179 static PyObject *Lamp_getSamples( BPy_Lamp * self );
180 static PyObject *Lamp_getBufferSize( BPy_Lamp * self );
181 static PyObject *Lamp_getHaloStep( BPy_Lamp * self );
182 static PyObject *Lamp_getEnergy( BPy_Lamp * self );
183 static PyObject *Lamp_getDist( BPy_Lamp * self );
184 static PyObject *Lamp_getSpotSize( BPy_Lamp * self );
185 static PyObject *Lamp_getSpotBlend( BPy_Lamp * self );
186 static PyObject *Lamp_getClipStart( BPy_Lamp * self );
187 static PyObject *Lamp_getClipEnd( BPy_Lamp * self );
188 static PyObject *Lamp_getBias( BPy_Lamp * self );
189 static PyObject *Lamp_getSoftness( BPy_Lamp * self );
190 static PyObject *Lamp_getHaloInt( BPy_Lamp * self );
191 static PyObject *Lamp_getQuad1( BPy_Lamp * self );
192 static PyObject *Lamp_getQuad2( BPy_Lamp * self );
193 static PyObject *Lamp_getCol( BPy_Lamp * self );
194 static PyObject *Lamp_getIpo( BPy_Lamp * self );
195 static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure );
196 static PyObject *Lamp_getUsers( BPy_Lamp * self );
197 static PyObject *Lamp_clearIpo( BPy_Lamp * self );
198 static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args );
199 static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args );
200 static PyObject *Lamp_oldsetName( BPy_Lamp * self, PyObject * args );
201 static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * args );
202 static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args );
203 static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args );
204 static PyObject *Lamp_oldsetBufferSize( BPy_Lamp * self, PyObject * args );
205 static PyObject *Lamp_oldsetHaloStep( BPy_Lamp * self, PyObject * args );
206 static PyObject *Lamp_oldsetEnergy( BPy_Lamp * self, PyObject * args );
207 static PyObject *Lamp_oldsetDist( BPy_Lamp * self, PyObject * args );
208 static PyObject *Lamp_oldsetSpotSize( BPy_Lamp * self, PyObject * args );
209 static PyObject *Lamp_oldsetSpotBlend( BPy_Lamp * self, PyObject * args );
210 static PyObject *Lamp_oldsetClipStart( BPy_Lamp * self, PyObject * args );
211 static PyObject *Lamp_oldsetClipEnd( BPy_Lamp * self, PyObject * args );
212 static PyObject *Lamp_oldsetBias( BPy_Lamp * self, PyObject * args );
213 static PyObject *Lamp_oldsetSoftness( BPy_Lamp * self, PyObject * args );
214 static PyObject *Lamp_oldsetHaloInt( BPy_Lamp * self, PyObject * args );
215 static PyObject *Lamp_oldsetQuad1( BPy_Lamp * self, PyObject * args );
216 static PyObject *Lamp_oldsetQuad2( BPy_Lamp * self, PyObject * args );
217 static PyObject *Lamp_oldsetCol( BPy_Lamp * self, PyObject * args );
218 static int Lamp_setIpo( BPy_Lamp * self, PyObject * args );
219 static int Lamp_setName( BPy_Lamp * self, PyObject * args );
220 static int Lamp_setType( BPy_Lamp * self, PyObject * args );
221 static int Lamp_setMode( BPy_Lamp * self, PyObject * args );
222 static int Lamp_setSamples( BPy_Lamp * self, PyObject * args );
223 static int Lamp_setBufferSize( BPy_Lamp * self, PyObject * args );
224 static int Lamp_setHaloStep( BPy_Lamp * self, PyObject * args );
225 static int Lamp_setEnergy( BPy_Lamp * self, PyObject * args );
226 static int Lamp_setDist( BPy_Lamp * self, PyObject * args );
227 static int Lamp_setSpotSize( BPy_Lamp * self, PyObject * args );
228 static int Lamp_setSpotBlend( BPy_Lamp * self, PyObject * args );
229 static int Lamp_setClipStart( BPy_Lamp * self, PyObject * args );
230 static int Lamp_setClipEnd( BPy_Lamp * self, PyObject * args );
231 static int Lamp_setBias( BPy_Lamp * self, PyObject * args );
232 static int Lamp_setSoftness( BPy_Lamp * self, PyObject * args );
233 static int Lamp_setHaloInt( BPy_Lamp * self, PyObject * args );
234 static int Lamp_setQuad1( BPy_Lamp * self, PyObject * args );
235 static int Lamp_setQuad2( BPy_Lamp * self, PyObject * args );
236 static int Lamp_setCol( BPy_Lamp * self, PyObject * args );
237 static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args );
238 static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args );
239 static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args );
240 static int Lamp_setComponent( BPy_Lamp * self, PyObject * value, void * closure );
241
242 /*****************************************************************************/
243 /* Python BPy_Lamp methods table:                                            */
244 /*****************************************************************************/
245 static PyMethodDef BPy_Lamp_methods[] = {
246         /* name, method, flags, doc */
247         {"getName", ( PyCFunction ) Lamp_getName, METH_NOARGS,
248          "() - return Lamp name"},
249         {"getType", ( PyCFunction ) Lamp_getType, METH_NOARGS,
250          "() - return Lamp type - 'Lamp':0, 'Sun':1, 'Spot':2, 'Hemi':3, 'Area':4, 'Photon':5"},
251         {"getMode", ( PyCFunction ) Lamp_getMode, METH_NOARGS,
252          "() - return Lamp mode flags (or'ed value)"},
253         {"getSamples", ( PyCFunction ) Lamp_getSamples, METH_NOARGS,
254          "() - return Lamp samples value"},
255         {"getBufferSize", ( PyCFunction ) Lamp_getBufferSize, METH_NOARGS,
256          "() - return Lamp buffer size value"},
257         {"getHaloStep", ( PyCFunction ) Lamp_getHaloStep, METH_NOARGS,
258          "() - return Lamp halo step value"},
259         {"getEnergy", ( PyCFunction ) Lamp_getEnergy, METH_NOARGS,
260          "() - return Lamp energy value"},
261         {"getDist", ( PyCFunction ) Lamp_getDist, METH_NOARGS,
262          "() - return Lamp clipping distance value"},
263         {"getSpotSize", ( PyCFunction ) Lamp_getSpotSize, METH_NOARGS,
264          "() - return Lamp spot size value"},
265         {"getSpotBlend", ( PyCFunction ) Lamp_getSpotBlend, METH_NOARGS,
266          "() - return Lamp spot blend value"},
267         {"getClipStart", ( PyCFunction ) Lamp_getClipStart, METH_NOARGS,
268          "() - return Lamp clip start value"},
269         {"getClipEnd", ( PyCFunction ) Lamp_getClipEnd, METH_NOARGS,
270          "() - return Lamp clip end value"},
271         {"getBias", ( PyCFunction ) Lamp_getBias, METH_NOARGS,
272          "() - return Lamp bias value"},
273         {"getSoftness", ( PyCFunction ) Lamp_getSoftness, METH_NOARGS,
274          "() - return Lamp softness value"},
275         {"getHaloInt", ( PyCFunction ) Lamp_getHaloInt, METH_NOARGS,
276          "() - return Lamp halo intensity value"},
277         {"getQuad1", ( PyCFunction ) Lamp_getQuad1, METH_NOARGS,
278          "() - return light intensity value #1 for a Quad Lamp"},
279         {"getQuad2", ( PyCFunction ) Lamp_getQuad2, METH_NOARGS,
280          "() - return light intensity value #2 for a Quad Lamp"},
281         {"getCol", ( PyCFunction ) Lamp_getCol, METH_NOARGS,
282          "() - return light rgb color triplet"},
283         {"setName", ( PyCFunction ) Lamp_oldsetName, METH_VARARGS,
284          "(str) - rename Lamp"},
285         {"setType", ( PyCFunction ) Lamp_oldsetType, METH_VARARGS,
286          "(str) - change Lamp type, which can be 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', 'Photon'"},
287         {"setMode", ( PyCFunction ) Lamp_oldsetMode, METH_VARARGS,
288          "([up to eight str's]) - Set Lamp mode flag(s)"},
289         {"setSamples", ( PyCFunction ) Lamp_oldsetSamples, METH_VARARGS,
290          "(int) - change Lamp samples value"},
291         {"setBufferSize", ( PyCFunction ) Lamp_oldsetBufferSize, METH_VARARGS,
292          "(int) - change Lamp buffer size value"},
293         {"setHaloStep", ( PyCFunction ) Lamp_oldsetHaloStep, METH_VARARGS,
294          "(int) - change Lamp halo step value"},
295         {"setEnergy", ( PyCFunction ) Lamp_oldsetEnergy, METH_VARARGS,
296          "(float) - change Lamp energy value"},
297         {"setDist", ( PyCFunction ) Lamp_oldsetDist, METH_VARARGS,
298          "(float) - change Lamp clipping distance value"},
299         {"setSpotSize", ( PyCFunction ) Lamp_oldsetSpotSize, METH_VARARGS,
300          "(float) - change Lamp spot size value"},
301         {"setSpotBlend", ( PyCFunction ) Lamp_oldsetSpotBlend, METH_VARARGS,
302          "(float) - change Lamp spot blend value"},
303         {"setClipStart", ( PyCFunction ) Lamp_oldsetClipStart, METH_VARARGS,
304          "(float) - change Lamp clip start value"},
305         {"setClipEnd", ( PyCFunction ) Lamp_oldsetClipEnd, METH_VARARGS,
306          "(float) - change Lamp clip end value"},
307         {"setBias", ( PyCFunction ) Lamp_oldsetBias, METH_VARARGS,
308          "(float) - change Lamp draw size value"},
309         {"setSoftness", ( PyCFunction ) Lamp_oldsetSoftness, METH_VARARGS,
310          "(float) - change Lamp softness value"},
311         {"setHaloInt", ( PyCFunction ) Lamp_oldsetHaloInt, METH_VARARGS,
312          "(float) - change Lamp halo intensity value"},
313         {"setQuad1", ( PyCFunction ) Lamp_oldsetQuad1, METH_VARARGS,
314          "(float) - change light intensity value #1 for a Quad Lamp"},
315         {"setQuad2", ( PyCFunction ) Lamp_oldsetQuad2, METH_VARARGS,
316          "(float) - change light intensity value #2 for a Quad Lamp"},
317         {"setCol", ( PyCFunction ) Lamp_oldsetCol, METH_VARARGS,
318          "(f,f,f) or ([f,f,f]) - change light's rgb color triplet"},
319         {"getScriptLinks", ( PyCFunction ) Lamp_getScriptLinks, METH_VARARGS,
320          "(eventname) - Get a list of this lamp's scriptlinks (Text names) "
321          "of the given type\n"
322          "(eventname) - string: FrameChanged, Redraw or Render."},
323         {"addScriptLink", ( PyCFunction ) Lamp_addScriptLink, METH_VARARGS,
324          "(text, evt) - Add a new lamp scriptlink.\n"
325          "(text) - string: an existing Blender Text name;\n"
326          "(evt) string: FrameChanged, Redraw or Render."},
327         {"clearScriptLinks", ( PyCFunction ) Lamp_clearScriptLinks,
328          METH_VARARGS,
329          "() - Delete all scriptlinks from this lamp.\n"
330          "([s1<,s2,s3...>]) - Delete specified scriptlinks from this lamp."},
331         {"getIpo", ( PyCFunction ) Lamp_getIpo, METH_NOARGS,
332          "() - get IPO for this lamp"},
333         {"clearIpo", ( PyCFunction ) Lamp_clearIpo, METH_NOARGS,
334          "() - unlink the IPO for this lamp"},
335         {"setIpo", ( PyCFunction ) Lamp_oldsetIpo, METH_VARARGS,
336          "( lamp-ipo ) - link an IPO to this lamp"},
337          {"insertIpoKey", ( PyCFunction ) Lamp_insertIpoKey, METH_VARARGS,
338          "( Lamp IPO type ) - Inserts a key into IPO"},
339
340         {NULL, NULL, 0, NULL}
341 };
342
343 /*****************************************************************************/
344 /* Python attributes get/set structure:                                      */
345 /*****************************************************************************/
346 static PyGetSetDef BPy_Lamp_getseters[] = {
347         {"bias",
348          (getter)Lamp_getBias, (setter)Lamp_setBias,
349          "Lamp shadow map sampling bias",
350          NULL},
351         {"bufferSize",
352          (getter)Lamp_getBufferSize, (setter)Lamp_setBufferSize,
353          "Lamp shadow buffer size",
354          NULL},
355         {"clipEnd",
356          (getter)Lamp_getClipEnd, (setter)Lamp_setClipEnd,
357          "Lamp shadow map clip end",
358          NULL},
359         {"clipStart",
360          (getter)Lamp_getClipStart, (setter)Lamp_setClipStart,
361          "Lamp shadow map clip start",
362          NULL},
363         {"col",
364          (getter)Lamp_getCol, (setter)Lamp_setCol,
365          "Lamp RGB color triplet",
366          NULL},
367         {"dist",
368          (getter)Lamp_getDist, (setter)Lamp_setDist,
369          "Lamp clipping distance",
370          NULL},
371         {"energy",
372          (getter)Lamp_getEnergy, (setter)Lamp_setEnergy,
373          "Lamp light intensity",
374          NULL},
375         {"haloInt",
376          (getter)Lamp_getHaloInt, (setter)Lamp_setHaloInt,
377          "Lamp spotlight halo intensity",
378          NULL},
379         {"haloStep",
380          (getter)Lamp_getHaloStep, (setter)Lamp_setHaloStep,
381          "Lamp volumetric halo sampling frequency",
382          NULL},
383         {"ipo",
384          (getter)Lamp_getIpo, (setter)Lamp_setIpo,
385          "Lamp Ipo",
386          NULL},
387         {"mode",
388          (getter)Lamp_getMode, (setter)Lamp_setMode,
389          "Lamp mode bitmask",
390          NULL},
391         {"name",
392          (getter)Lamp_getName, (setter)Lamp_setName,
393          "Lamp data name",
394          NULL},
395         {"quad1",
396          (getter)Lamp_getQuad1, (setter)Lamp_setQuad1,
397          "Quad lamp linear distance attenuation",
398          NULL},
399         {"quad2",
400          (getter)Lamp_getQuad2, (setter)Lamp_setQuad2,
401          "Quad lamp quadratic distance attenuation",
402          NULL},
403         {"samples",
404          (getter)Lamp_getSamples, (setter)Lamp_setSamples,
405          "Lamp shadow map samples",
406          NULL},
407         {"softness",
408          (getter)Lamp_getSoftness, (setter)Lamp_setSoftness,
409          "Lamp shadow sample area size",
410          NULL},
411         {"spotBlend",
412          (getter)Lamp_getSpotBlend, (setter)Lamp_setSpotBlend,
413          "Lamp spotlight edge softness",
414          NULL},
415         {"spotSize",
416          (getter)Lamp_getSpotSize, (setter)Lamp_setSpotSize,
417          "Lamp spotlight beam angle (in degrees)",
418          NULL},
419         {"type",
420          (getter)Lamp_getType, (setter)Lamp_setType,
421          "Lamp type",
422          NULL},
423         {"R",
424          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
425          "Lamp color red component",
426          (void *)EXPP_LAMP_COMP_R},
427         {"r",
428          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
429          "Lamp color red component",
430          (void *)EXPP_LAMP_COMP_R},
431         {"G",
432          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
433          "Lamp color green component",
434          (void *)EXPP_LAMP_COMP_G},
435         {"g",
436          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
437          "Lamp color green component",
438          (void *)EXPP_LAMP_COMP_G},
439         {"B",
440          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
441          "Lamp color blue component",
442          (void *)EXPP_LAMP_COMP_B},
443         {"b",
444          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
445          "Lamp color blue component",
446          (void *)EXPP_LAMP_COMP_B},
447         {"users",
448          (getter)Lamp_getUsers, (setter)NULL,
449          "Number of lamp users",
450          NULL},
451         {"Modes",
452          (getter)Lamp_getModesConst, (setter)NULL,
453          "Dictionary of values for 'mode' attribute",
454          NULL},
455         {"Types",
456          (getter)Lamp_getTypesConst, (setter)NULL,
457          "Dictionary of values for 'type' attribute",
458          NULL},
459         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
460 };
461
462 /*****************************************************************************/
463 /* Python TypeLamp callback function prototypes:                             */
464 /*****************************************************************************/
465 static void Lamp_dealloc( BPy_Lamp * lamp );
466 static int Lamp_compare( BPy_Lamp * a, BPy_Lamp * b );
467 static PyObject *Lamp_repr( BPy_Lamp * lamp );
468
469 /*****************************************************************************/
470 /* Python TypeLamp structure definition:                                     */
471 /*****************************************************************************/
472 PyTypeObject Lamp_Type = {
473         PyObject_HEAD_INIT( NULL )  /* required py macro */
474         0,                          /* ob_size */
475         /*  For printing, in format "<module>.<name>" */
476         "Blender Lamp",             /* char *tp_name; */
477         sizeof( BPy_Lamp ),         /* int tp_basicsize; */
478         0,                          /* tp_itemsize;  For allocation */
479
480         /* Methods to implement standard operations */
481
482         ( destructor ) Lamp_dealloc,/* destructor tp_dealloc; */
483         NULL,                       /* printfunc tp_print; */
484         NULL,                       /* getattrfunc tp_getattr; */
485         NULL,                       /* setattrfunc tp_setattr; */
486         ( cmpfunc ) Lamp_compare,   /* cmpfunc tp_compare; */
487         ( reprfunc ) Lamp_repr,     /* reprfunc tp_repr; */
488
489         /* Method suites for standard classes */
490
491         NULL,                       /* PyNumberMethods *tp_as_number; */
492         NULL,                       /* PySequenceMethods *tp_as_sequence; */
493         NULL,                       /* PyMappingMethods *tp_as_mapping; */
494
495         /* More standard operations (here for binary compatibility) */
496
497         NULL,                       /* hashfunc tp_hash; */
498         NULL,                       /* ternaryfunc tp_call; */
499         NULL,                       /* reprfunc tp_str; */
500         NULL,                       /* getattrofunc tp_getattro; */
501         NULL,                       /* setattrofunc tp_setattro; */
502
503         /* Functions to access object as input/output buffer */
504         NULL,                       /* PyBufferProcs *tp_as_buffer; */
505
506   /*** Flags to define presence of optional/expanded features ***/
507         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
508
509         NULL,                       /*  char *tp_doc;  Documentation string */
510   /*** Assigned meaning in release 2.0 ***/
511         /* call function for all accessible objects */
512         NULL,                       /* traverseproc tp_traverse; */
513
514         /* delete references to contained objects */
515         NULL,                       /* inquiry tp_clear; */
516
517   /***  Assigned meaning in release 2.1 ***/
518   /*** rich comparisons ***/
519         NULL,                       /* richcmpfunc tp_richcompare; */
520
521   /***  weak reference enabler ***/
522         0,                          /* long tp_weaklistoffset; */
523
524   /*** Added in release 2.2 ***/
525         /*   Iterators */
526         NULL,                       /* getiterfunc tp_iter; */
527         NULL,                       /* iternextfunc tp_iternext; */
528
529   /*** Attribute descriptor and subclassing stuff ***/
530         BPy_Lamp_methods,           /* struct PyMethodDef *tp_methods; */
531         NULL,                       /* struct PyMemberDef *tp_members; */
532         BPy_Lamp_getseters,         /* struct PyGetSetDef *tp_getset; */
533         NULL,                       /* struct _typeobject *tp_base; */
534         NULL,                       /* PyObject *tp_dict; */
535         NULL,                       /* descrgetfunc tp_descr_get; */
536         NULL,                       /* descrsetfunc tp_descr_set; */
537         0,                          /* long tp_dictoffset; */
538         NULL,                       /* initproc tp_init; */
539         NULL,                       /* allocfunc tp_alloc; */
540         NULL,                       /* newfunc tp_new; */
541         /*  Low-level free-memory routine */
542         NULL,                       /* freefunc tp_free;  */
543         /* For PyObject_IS_GC */
544         NULL,                       /* inquiry tp_is_gc;  */
545         NULL,                       /* PyObject *tp_bases; */
546         /* method resolution order */
547         NULL,                       /* PyObject *tp_mro;  */
548         NULL,                       /* PyObject *tp_cache; */
549         NULL,                       /* PyObject *tp_subclasses; */
550         NULL,                       /* PyObject *tp_weaklist; */
551         NULL
552 };
553
554 /*****************************************************************************/
555 /* Function:              M_Lamp_New                                         */
556 /* Python equivalent:     Blender.Lamp.New                                   */
557 /*****************************************************************************/
558 static PyObject *M_Lamp_New( PyObject * self, PyObject * args,
559                              PyObject * keywords )
560 {
561         char *type_str = "Lamp";
562         char *name_str = "LampData";
563         static char *kwlist[] = { "type_str", "name_str", NULL };
564         BPy_Lamp *py_lamp;      /* for Lamp Data object wrapper in Python */
565         Lamp *bl_lamp;          /* for actual Lamp Data we create in Blender */
566         char buf[21];
567
568         if( !PyArg_ParseTupleAndKeywords( args, keywords, "|ss", kwlist,
569                                           &type_str, &name_str ) )
570                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
571                                                 "expected string(s) or empty argument" ) );
572
573         bl_lamp = add_lamp(  ); /* first create in Blender */
574         if( bl_lamp )           /* now create the wrapper obj in Python */
575                 py_lamp = ( BPy_Lamp * ) Lamp_CreatePyObject( bl_lamp );
576         else
577                 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
578                                                 "couldn't create Lamp Data in Blender" ) );
579
580         /* let's return user count to zero, because ... */
581         bl_lamp->id.us = 0;     /* ... add_lamp() incref'ed it */
582
583         if( py_lamp == NULL )
584                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
585                                                 "couldn't create Lamp Data object" ) );
586
587         if( strcmp( type_str, "Lamp" ) == 0 )
588                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_LAMP;
589         else if( strcmp( type_str, "Sun" ) == 0 )
590                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_SUN;
591         else if( strcmp( type_str, "Spot" ) == 0 )
592                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_SPOT;
593         else if( strcmp( type_str, "Hemi" ) == 0 )
594                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_HEMI;
595         else if( strcmp( type_str, "Area" ) == 0 )
596                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_AREA;
597         else if( strcmp( type_str, "Photon" ) == 0 )
598                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_YF_PHOTON;
599         else
600                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
601                                                 "unknown lamp type" ) );
602
603         if( strcmp( name_str, "LampData" ) == 0 )
604                 return ( PyObject * ) py_lamp;
605         else {                  /* user gave us a name for the lamp, use it */
606                 PyOS_snprintf( buf, sizeof( buf ), "%s", name_str );
607                 rename_id( &bl_lamp->id, buf );
608         }
609
610         return ( PyObject * ) py_lamp;
611 }
612
613 /*****************************************************************************/
614 /* Function:              M_Lamp_Get                                         */
615 /* Python equivalent:     Blender.Lamp.Get                                   */
616 /* Description:           Receives a string and returns the lamp data obj    */
617 /*                        whose name matches the string.  If no argument is  */
618 /*                        passed in, a list of all lamp data names in the    */
619 /*                        current scene is returned.                         */
620 /*****************************************************************************/
621 static PyObject *M_Lamp_Get( PyObject * self, PyObject * args )
622 {
623         char *name = NULL;
624         Lamp *lamp_iter;
625
626         if( !PyArg_ParseTuple( args, "|s", &name ) )
627                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
628                                                 "expected string argument (or nothing)" ) );
629
630         lamp_iter = G.main->lamp.first;
631
632         if( name ) {            /* (name) - Search lamp by name */
633
634                 BPy_Lamp *wanted_lamp = NULL;
635
636                 while( ( lamp_iter ) && ( wanted_lamp == NULL ) ) {
637
638                         if( strcmp( name, lamp_iter->id.name + 2 ) == 0 )
639                                 wanted_lamp =
640                                         ( BPy_Lamp * )
641                                         Lamp_CreatePyObject( lamp_iter );
642
643                         lamp_iter = lamp_iter->id.next;
644                 }
645
646                 if( wanted_lamp == NULL ) { /* Requested lamp doesn't exist */
647                         char error_msg[64];
648                         PyOS_snprintf( error_msg, sizeof( error_msg ),
649                                        "Lamp \"%s\" not found", name );
650                         return ( EXPP_ReturnPyObjError
651                                  ( PyExc_NameError, error_msg ) );
652                 }
653
654                 return ( PyObject * ) wanted_lamp;
655         }
656
657         else {          /* () - return a list of all lamps in the scene */
658                 int index = 0;
659                 PyObject *lamplist, *pyobj;
660
661                 lamplist = PyList_New( BLI_countlist( &( G.main->lamp ) ) );
662
663                 if( lamplist == NULL )
664                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
665                                                         "couldn't create PyList" ) );
666
667                 while( lamp_iter ) {
668                         pyobj = Lamp_CreatePyObject( lamp_iter );
669
670                         if( !pyobj )
671                                 return ( EXPP_ReturnPyObjError
672                                          ( PyExc_MemoryError,
673                                            "couldn't create PyString" ) );
674
675                         PyList_SET_ITEM( lamplist, index, pyobj );
676
677                         lamp_iter = lamp_iter->id.next;
678                         index++;
679                 }
680
681                 return lamplist;
682         }
683 }
684
685 static PyObject *Lamp_TypesDict( void )
686 {       /* create the Blender.Lamp.Types constant dict */
687         PyObject *Types = PyConstant_New(  );
688
689         if( Types ) {
690                 BPy_constant *c = ( BPy_constant * ) Types;
691
692                 PyConstant_Insert( c, "Lamp",
693                                  PyInt_FromLong( EXPP_LAMP_TYPE_LAMP ) );
694                 PyConstant_Insert( c, "Sun",
695                                  PyInt_FromLong( EXPP_LAMP_TYPE_SUN ) );
696                 PyConstant_Insert( c, "Spot",
697                                  PyInt_FromLong( EXPP_LAMP_TYPE_SPOT ) );
698                 PyConstant_Insert( c, "Hemi",
699                                  PyInt_FromLong( EXPP_LAMP_TYPE_HEMI ) );
700                 PyConstant_Insert( c, "Area",
701                                  PyInt_FromLong( EXPP_LAMP_TYPE_AREA ) );
702                 PyConstant_Insert( c, "Photon",
703                                  PyInt_FromLong( EXPP_LAMP_TYPE_YF_PHOTON ) );
704         }
705
706         return Types;
707 }
708
709 static PyObject *Lamp_ModesDict( void )
710 {                       /* create the Blender.Lamp.Modes constant dict */
711         PyObject *Modes = PyConstant_New(  );
712
713         if( Modes ) {
714                 BPy_constant *c = ( BPy_constant * ) Modes;
715
716                 PyConstant_Insert( c, "Shadows",
717                                  PyInt_FromLong( EXPP_LAMP_MODE_SHADOWS ) );
718                 PyConstant_Insert( c, "Halo",
719                                  PyInt_FromLong( EXPP_LAMP_MODE_HALO ) );
720                 PyConstant_Insert( c, "Layer",
721                                  PyInt_FromLong( EXPP_LAMP_MODE_LAYER ) );
722                 PyConstant_Insert( c, "Quad",
723                                  PyInt_FromLong( EXPP_LAMP_MODE_QUAD ) );
724                 PyConstant_Insert( c, "Negative",
725                                  PyInt_FromLong( EXPP_LAMP_MODE_NEGATIVE ) );
726                 PyConstant_Insert( c, "Sphere",
727                                  PyInt_FromLong( EXPP_LAMP_MODE_SPHERE ) );
728                 PyConstant_Insert( c, "Square",
729                                  PyInt_FromLong( EXPP_LAMP_MODE_SQUARE ) );
730                 PyConstant_Insert( c, "OnlyShadow",
731                                  PyInt_FromLong( EXPP_LAMP_MODE_ONLYSHADOW ) );
732                 PyConstant_Insert( c, "NoDiffuse",
733                                  PyInt_FromLong( EXPP_LAMP_MODE_NODIFFUSE ) );
734                 PyConstant_Insert( c, "NoSpecular",
735                                  PyInt_FromLong( EXPP_LAMP_MODE_NOSPECULAR ) );
736         }
737
738         return Modes;
739 }
740
741 /*****************************************************************************/
742 /* Function:              Lamp_Init                                          */
743 /*****************************************************************************/
744 /* Needed by the Blender module, to register the Blender.Lamp submodule */
745 PyObject *Lamp_Init( void )
746 {
747         PyObject *submodule, *Types, *Modes;
748
749         if( PyType_Ready( &Lamp_Type ) < 0)
750                 return NULL;
751
752         Types = Lamp_TypesDict(  );
753         Modes = Lamp_ModesDict(  );
754
755         submodule =
756                 Py_InitModule3( "Blender.Lamp", M_Lamp_methods, M_Lamp_doc );
757
758         if( Types )
759                 PyModule_AddObject( submodule, "Types", Types );
760         if( Modes )
761                 PyModule_AddObject( submodule, "Modes", Modes );
762
763         PyModule_AddIntConstant( submodule, "RGB",      IPOKEY_RGB );
764         PyModule_AddIntConstant( submodule, "ENERGY",   IPOKEY_ENERGY );
765         PyModule_AddIntConstant( submodule, "SPOTSIZE", IPOKEY_SPOTSIZE );
766         PyModule_AddIntConstant( submodule, "OFFSET",   IPOKEY_OFFSET );
767         PyModule_AddIntConstant( submodule, "SIZE",     IPOKEY_SIZE );
768         
769         return submodule;
770 }
771
772 /* Three Python Lamp_Type helper functions needed by the Object module: */
773
774 /*****************************************************************************/
775 /* Function:    Lamp_CreatePyObject                                          */
776 /* Description: This function will create a new BPy_Lamp from an existing    */
777 /*              Blender lamp structure.                                      */
778 /*****************************************************************************/
779 PyObject *Lamp_CreatePyObject( Lamp * lamp )
780 {
781         BPy_Lamp *pylamp;
782         float *rgb[3];
783
784         pylamp = ( BPy_Lamp * ) PyObject_NEW( BPy_Lamp, &Lamp_Type );
785
786         if( !pylamp )
787                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
788                                               "couldn't create BPy_Lamp object" );
789
790         pylamp->lamp = lamp;
791
792         rgb[0] = &lamp->r;
793         rgb[1] = &lamp->g;
794         rgb[2] = &lamp->b;
795
796         pylamp->color = ( BPy_rgbTuple * ) rgbTuple_New( rgb );
797
798         return ( PyObject * ) pylamp;
799 }
800
801 /*****************************************************************************/
802 /* Function:    Lamp_CheckPyObject                                           */
803 /* Description: This function returns true when the given PyObject is of the */
804 /*              type Lamp. Otherwise it will return false.                   */
805 /*****************************************************************************/
806 int Lamp_CheckPyObject( PyObject * pyobj )
807 {
808         return ( pyobj->ob_type == &Lamp_Type );
809 }
810
811 /*****************************************************************************/
812 /* Function:    Lamp_FromPyObject                                            */
813 /* Description: This function returns the Blender lamp from the given        */
814 /*              PyObject.                                                    */
815 /*****************************************************************************/
816 Lamp *Lamp_FromPyObject( PyObject * pyobj )
817 {
818         return ( ( BPy_Lamp * ) pyobj )->lamp;
819 }
820
821 /*****************************************************************************/
822 /* Description: Returns the lamp with the name specified by the argument     */
823 /*              name. Note that the calling function has to remove the first */
824 /*              two characters of the lamp name. These two characters        */
825 /*              specify the type of the object (OB, ME, WO, ...)             */
826 /*              The function will return NULL when no lamp with the given    */
827 /*              name is found.                                               */
828 /*****************************************************************************/
829 Lamp *GetLampByName( char *name )
830 {
831         Lamp *lamp_iter;
832
833         lamp_iter = G.main->lamp.first;
834         while( lamp_iter ) {
835                 if( StringEqual( name, GetIdName( &( lamp_iter->id ) ) ) ) {
836                         return lamp_iter;
837                 }
838                 lamp_iter = lamp_iter->id.next;
839         }
840
841         /* There is no lamp with the given name */
842         return NULL;
843 }
844
845 /*****************************************************************************/
846 /* Python BPy_Lamp methods:                                                  */
847 /*****************************************************************************/
848 static PyObject *Lamp_getName( BPy_Lamp * self )
849 {
850         PyObject *attr = PyString_FromString( self->lamp->id.name + 2 );
851
852         if( attr )
853                 return attr;
854
855         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
856                                         "couldn't get Lamp.name attribute" ) );
857 }
858
859 static PyObject *Lamp_getType( BPy_Lamp * self )
860 {
861         PyObject *attr = PyInt_FromLong( self->lamp->type );
862
863         if( attr )
864                 return attr;
865
866         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
867                                         "couldn't get Lamp.type attribute" ) );
868 }
869
870 static PyObject *Lamp_getMode( BPy_Lamp * self )
871 {
872         PyObject *attr = PyInt_FromLong( self->lamp->mode );
873
874         if( attr )
875                 return attr;
876
877         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
878                                         "couldn't get Lamp.mode attribute" ) );
879 }
880
881 static PyObject *Lamp_getSamples( BPy_Lamp * self )
882 {
883         PyObject *attr = PyInt_FromLong( self->lamp->samp );
884
885         if( attr )
886                 return attr;
887
888         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
889                                         "couldn't get Lamp.samples attribute" ) );
890 }
891
892 static PyObject *Lamp_getBufferSize( BPy_Lamp * self )
893 {
894         PyObject *attr = PyInt_FromLong( self->lamp->bufsize );
895
896         if( attr )
897                 return attr;
898
899         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
900                                         "couldn't get Lamp.bufferSize attribute" ) );
901 }
902
903 static PyObject *Lamp_getHaloStep( BPy_Lamp * self )
904 {
905         PyObject *attr = PyInt_FromLong( self->lamp->shadhalostep );
906
907         if( attr )
908                 return attr;
909
910         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
911                                         "couldn't get Lamp.haloStep attribute" ) );
912 }
913
914 static PyObject *Lamp_getEnergy( BPy_Lamp * self )
915 {
916         PyObject *attr = PyFloat_FromDouble( self->lamp->energy );
917
918         if( attr )
919                 return attr;
920
921         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
922                                         "couldn't get Lamp.energy attribute" ) );
923 }
924
925 static PyObject *Lamp_getDist( BPy_Lamp * self )
926 {
927         PyObject *attr = PyFloat_FromDouble( self->lamp->dist );
928
929         if( attr )
930                 return attr;
931
932         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
933                                         "couldn't get Lamp.dist attribute" ) );
934 }
935
936 static PyObject *Lamp_getSpotSize( BPy_Lamp * self )
937 {
938         PyObject *attr = PyFloat_FromDouble( self->lamp->spotsize );
939
940         if( attr )
941                 return attr;
942
943         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
944                                         "couldn't get Lamp.spotSize attribute" ) );
945 }
946
947 static PyObject *Lamp_getSpotBlend( BPy_Lamp * self )
948 {
949         PyObject *attr = PyFloat_FromDouble( self->lamp->spotblend );
950
951         if( attr )
952                 return attr;
953
954         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
955                                         "couldn't get Lamp.spotBlend attribute" ) );
956 }
957
958 static PyObject *Lamp_getClipStart( BPy_Lamp * self )
959 {
960         PyObject *attr = PyFloat_FromDouble( self->lamp->clipsta );
961
962         if( attr )
963                 return attr;
964
965         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
966                                         "couldn't get Lamp.clipStart attribute" ) );
967 }
968
969 static PyObject *Lamp_getClipEnd( BPy_Lamp * self )
970 {
971         PyObject *attr = PyFloat_FromDouble( self->lamp->clipend );
972
973         if( attr )
974                 return attr;
975
976         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
977                                         "couldn't get Lamp.clipEnd attribute" ) );
978 }
979
980 static PyObject *Lamp_getBias( BPy_Lamp * self )
981 {
982         PyObject *attr = PyFloat_FromDouble( self->lamp->bias );
983
984         if( attr )
985                 return attr;
986
987         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
988                                         "couldn't get Lamp.bias attribute" ) );
989 }
990
991 static PyObject *Lamp_getSoftness( BPy_Lamp * self )
992 {
993         PyObject *attr = PyFloat_FromDouble( self->lamp->soft );
994
995         if( attr )
996                 return attr;
997
998         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
999                                         "couldn't get Lamp.softness attribute" ) );
1000 }
1001
1002 static PyObject *Lamp_getHaloInt( BPy_Lamp * self )
1003 {
1004         PyObject *attr = PyFloat_FromDouble( self->lamp->haint );
1005
1006         if( attr )
1007                 return attr;
1008
1009         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1010                                         "couldn't get Lamp.haloInt attribute" ) );
1011 }
1012
1013 static PyObject *Lamp_getQuad1( BPy_Lamp * self )
1014 {                               /* should we complain if Lamp is not of type Quad? */
1015         PyObject *attr = PyFloat_FromDouble( self->lamp->att1 );
1016
1017         if( attr )
1018                 return attr;
1019
1020         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1021                                         "couldn't get Lamp.quad1 attribute" ) );
1022 }
1023
1024 static PyObject *Lamp_getQuad2( BPy_Lamp * self )
1025 {                       /* should we complain if Lamp is not of type Quad? */
1026         PyObject *attr = PyFloat_FromDouble( self->lamp->att2 );
1027
1028         if( attr )
1029                 return attr;
1030
1031         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1032                                         "couldn't get Lamp.quad2 attribute" ) );
1033 }
1034
1035 static PyObject *Lamp_getCol( BPy_Lamp * self )
1036 {
1037         return rgbTuple_getCol( self->color );
1038 }
1039
1040 static int Lamp_setName( BPy_Lamp * self, PyObject * value )
1041 {
1042         char *name = NULL;
1043         char buf[21];
1044
1045         name = PyString_AsString ( value );
1046         if( !name )
1047                 return EXPP_ReturnIntError( PyExc_TypeError,
1048                                               "expected string argument" );
1049
1050         PyOS_snprintf( buf, sizeof( buf ), "%s", name );
1051
1052         rename_id( &self->lamp->id, buf );
1053
1054         return 0;
1055 }
1056
1057 static int Lamp_setType( BPy_Lamp * self, PyObject * value )
1058 {
1059         return EXPP_setIValueRange ( value, &self->lamp->type,
1060                                                                 0, EXPP_LAMP_TYPE_MAX, 'h' );
1061 }
1062
1063 static int Lamp_setMode( BPy_Lamp * self, PyObject * value )
1064 {
1065         short param;
1066         static short bitmask = EXPP_LAMP_MODE_SHADOWS
1067                                 | EXPP_LAMP_MODE_HALO
1068                                 | EXPP_LAMP_MODE_LAYER
1069                                 | EXPP_LAMP_MODE_QUAD
1070                                 | EXPP_LAMP_MODE_NEGATIVE
1071                                 | EXPP_LAMP_MODE_ONLYSHADOW
1072                                 | EXPP_LAMP_MODE_SPHERE
1073                                 | EXPP_LAMP_MODE_SQUARE
1074                                 | EXPP_LAMP_MODE_NODIFFUSE
1075                                 | EXPP_LAMP_MODE_NOSPECULAR;
1076
1077         if( !PyInt_CheckExact ( value ) ) {
1078                 char errstr[128];
1079                 sprintf ( errstr , "expected int bitmask of 0x%04x", bitmask );
1080                 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1081         }
1082         param = PyInt_AS_LONG ( value );
1083
1084         if ( ( param & bitmask ) != param )
1085                 return EXPP_ReturnIntError( PyExc_ValueError,
1086                                                 "invalid bit(s) set in mask" );
1087
1088         self->lamp->mode = param; 
1089
1090         return 0;
1091 }
1092
1093 static int Lamp_setSamples( BPy_Lamp * self, PyObject * value )
1094 {
1095         return EXPP_setIValueClamped ( value, &self->lamp->samp,
1096                                                                 EXPP_LAMP_SAMPLES_MIN,
1097                                                                 EXPP_LAMP_SAMPLES_MAX, 'h' );
1098 }
1099
1100 static int Lamp_setBufferSize( BPy_Lamp * self, PyObject * value )
1101 {
1102         return EXPP_setIValueClamped ( value, &self->lamp->bufsize,
1103                                                                 EXPP_LAMP_BUFFERSIZE_MIN,
1104                                                                 EXPP_LAMP_BUFFERSIZE_MAX, 'h' );
1105 }
1106
1107 static int Lamp_setHaloStep( BPy_Lamp * self, PyObject * value )
1108 {
1109         return EXPP_setIValueClamped ( value, &self->lamp->shadhalostep,
1110                                                                 EXPP_LAMP_HALOSTEP_MIN,
1111                                                                 EXPP_LAMP_HALOSTEP_MAX, 'h' );
1112 }
1113
1114 static int Lamp_setEnergy( BPy_Lamp * self, PyObject * value )
1115 {
1116         return EXPP_setFloatClamped ( value, &self->lamp->energy, 
1117                                                                 EXPP_LAMP_ENERGY_MIN,
1118                                                                 EXPP_LAMP_ENERGY_MAX );
1119 }
1120
1121 static int Lamp_setDist( BPy_Lamp * self, PyObject * value )
1122 {
1123         return EXPP_setFloatClamped ( value, &self->lamp->dist, 
1124                                                                 EXPP_LAMP_DIST_MIN,
1125                                                                 EXPP_LAMP_DIST_MAX );
1126 }
1127
1128 static int Lamp_setSpotSize( BPy_Lamp * self, PyObject * value )
1129 {
1130         return EXPP_setFloatClamped ( value, &self->lamp->spotsize, 
1131                                                                 EXPP_LAMP_SPOTSIZE_MIN,
1132                                                                 EXPP_LAMP_SPOTSIZE_MAX );
1133 }
1134
1135 static int Lamp_setSpotBlend( BPy_Lamp * self, PyObject * value )
1136 {
1137         return EXPP_setFloatClamped ( value, &self->lamp->spotblend, 
1138                                                                 EXPP_LAMP_SPOTBLEND_MIN,
1139                                                                 EXPP_LAMP_SPOTBLEND_MAX );
1140 }
1141
1142 static int Lamp_setClipStart( BPy_Lamp * self, PyObject * value )
1143 {
1144         return EXPP_setFloatClamped ( value, &self->lamp->clipsta, 
1145                                                                 EXPP_LAMP_CLIPSTART_MIN,
1146                                                                 EXPP_LAMP_CLIPSTART_MAX );
1147 }
1148
1149 static int Lamp_setClipEnd( BPy_Lamp * self, PyObject * value )
1150 {
1151         return EXPP_setFloatClamped ( value, &self->lamp->clipend, 
1152                                                                 EXPP_LAMP_CLIPEND_MIN,
1153                                                                 EXPP_LAMP_CLIPEND_MAX );
1154 }
1155
1156 static int Lamp_setBias( BPy_Lamp * self, PyObject * value )
1157 {
1158         return EXPP_setFloatClamped ( value, &self->lamp->bias,
1159                                                                 EXPP_LAMP_BIAS_MIN,
1160                                                                 EXPP_LAMP_BIAS_MAX );
1161 }
1162
1163 static int Lamp_setSoftness( BPy_Lamp * self, PyObject * value )
1164 {
1165         return EXPP_setFloatClamped ( value, &self->lamp->soft,
1166                                                                 EXPP_LAMP_SOFTNESS_MIN,
1167                                                                 EXPP_LAMP_SOFTNESS_MAX );
1168 }
1169
1170 static int Lamp_setHaloInt( BPy_Lamp * self, PyObject * value )
1171 {
1172         return EXPP_setFloatClamped ( value, &self->lamp->haint,
1173                                                                 EXPP_LAMP_HALOINT_MIN,
1174                                                                 EXPP_LAMP_HALOINT_MAX );
1175 }
1176
1177 static int Lamp_setQuad1( BPy_Lamp * self, PyObject * value )
1178 {
1179         return EXPP_setFloatClamped ( value, &self->lamp->att1,
1180                                                                 EXPP_LAMP_QUAD1_MIN,
1181                                                                 EXPP_LAMP_QUAD1_MAX );
1182 }
1183
1184 static int Lamp_setQuad2( BPy_Lamp * self, PyObject * value )
1185 {
1186         return EXPP_setFloatClamped ( value, &self->lamp->att2,
1187                                                                 EXPP_LAMP_QUAD2_MIN,
1188                                                                 EXPP_LAMP_QUAD2_MAX );
1189 }
1190
1191 static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure )
1192 {
1193         PyObject *attr = NULL;
1194
1195         switch ( (int)closure ) {
1196         case EXPP_LAMP_COMP_R:
1197                 attr = PyFloat_FromDouble( self->lamp->r );
1198                 break;
1199         case EXPP_LAMP_COMP_G:
1200                 attr = PyFloat_FromDouble( self->lamp->g );
1201                 break;
1202         case EXPP_LAMP_COMP_B:
1203                 attr = PyFloat_FromDouble( self->lamp->b );
1204                 break;
1205         default:
1206                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1207                                         "unknown color component specified" );
1208         }
1209
1210         if( !attr )
1211                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1212                                         "PyFloat_FromDouble() failed" );
1213         return attr;
1214 }
1215
1216 static int Lamp_setComponent( BPy_Lamp * self, PyObject * value,
1217                                                         void * closure )
1218 {
1219         float color;
1220
1221         if( !PyNumber_Check ( value ) )
1222                 return EXPP_ReturnIntError( PyExc_TypeError,
1223                                                 "expected float argument in [0.0,1.0]" );
1224
1225         color = PyFloat_AsDouble( value );
1226         color = EXPP_ClampFloat( color, EXPP_LAMP_COL_MIN, EXPP_LAMP_COL_MAX );
1227
1228         switch ( (int)closure ) {
1229         case EXPP_LAMP_COMP_R:
1230                 self->lamp->r = color;
1231                 return 0;
1232         case EXPP_LAMP_COMP_G:
1233                 self->lamp->g = color;
1234                 return 0;
1235         case EXPP_LAMP_COMP_B:
1236                 self->lamp->b = color;
1237                 return 0;
1238         }
1239         return EXPP_ReturnIntError( PyExc_RuntimeError,
1240                                 "unknown color component specified" );
1241 }
1242
1243 static int Lamp_setCol( BPy_Lamp * self, PyObject * args )
1244 {
1245         return rgbTuple_setCol( self->color, args );
1246 }
1247
1248 /* lamp.addScriptLink */
1249 static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args )
1250 {
1251         Lamp *lamp = self->lamp;
1252         ScriptLink *slink = NULL;
1253
1254         slink = &( lamp )->scriptlink;
1255
1256         return EXPP_addScriptLink( slink, args, 0 );
1257 }
1258
1259 /* lamp.clearScriptLinks */
1260 static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args )
1261 {
1262         Lamp *lamp = self->lamp;
1263         ScriptLink *slink = NULL;
1264
1265         slink = &( lamp )->scriptlink;
1266
1267         return EXPP_clearScriptLinks( slink, args );
1268 }
1269
1270 /* mat.getScriptLinks */
1271 static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args )
1272 {
1273         Lamp *lamp = self->lamp;
1274         ScriptLink *slink = NULL;
1275         PyObject *ret = NULL;
1276
1277         slink = &( lamp )->scriptlink;
1278
1279         ret = EXPP_getScriptLinks( slink, args, 0 );
1280
1281         if( ret )
1282                 return ret;
1283         else
1284                 return NULL;
1285 }
1286
1287 /*****************************************************************************/
1288 /* Function:    Lamp_dealloc                                                 */
1289 /* Description: This is a callback function for the BPy_Lamp type. It is     */
1290 /*              the destructor function.                                     */
1291 /*****************************************************************************/
1292 static void Lamp_dealloc( BPy_Lamp * self )
1293 {
1294         Py_DECREF( self->color );
1295         PyObject_DEL( self );
1296 }
1297
1298 /*****************************************************************************/
1299 /* Function:    Lamp_compare                                                 */
1300 /* Description: This is a callback function for the BPy_Lamp type. It        */
1301 /*              compares two Lamp_Type objects. Only the "==" and "!="       */
1302 /*              comparisons are meaningful. Returns 0 for equality and -1    */
1303 /*              if they don't point to the same Blender Lamp struct.         */
1304 /*              In Python it becomes 1 if they are equal, 0 otherwise.       */
1305 /*****************************************************************************/
1306 static int Lamp_compare( BPy_Lamp * a, BPy_Lamp * b )
1307 {
1308         Lamp *pa = a->lamp, *pb = b->lamp;
1309         return ( pa == pb ) ? 0 : -1;
1310 }
1311
1312 /*****************************************************************************/
1313 /* Function:    Lamp_repr                                                    */
1314 /* Description: This is a callback function for the BPy_Lamp type. It        */
1315 /*              builds a meaninful string to represent lamp objects.         */
1316 /*****************************************************************************/
1317 static PyObject *Lamp_repr( BPy_Lamp * self )
1318 {
1319         return PyString_FromFormat( "[Lamp \"%s\"]", self->lamp->id.name + 2 );
1320 }
1321
1322 static PyObject *Lamp_getIpo( BPy_Lamp * self )
1323 {
1324         struct Ipo *ipo = self->lamp->ipo;
1325
1326         if( !ipo ) {
1327                 Py_INCREF( Py_None );
1328                 return Py_None;
1329         }
1330
1331         return Ipo_CreatePyObject( ipo );
1332 }
1333
1334 /*
1335  * this should accept a Py_None argument and just delete the Ipo link
1336  * (as Lamp_clearIpo() does)
1337  */
1338
1339 static int Lamp_setIpo( BPy_Lamp * self, PyObject * value )
1340 {
1341         Ipo *ipo = NULL;
1342         Ipo *oldipo = self->lamp->ipo;
1343         ID *id;
1344
1345         /* if parameter is not None, check for valid Ipo */
1346
1347         if ( value != Py_None ) {
1348                 if ( !Ipo_CheckPyObject( value ) )
1349                         return EXPP_ReturnIntError( PyExc_RuntimeError,
1350                                                 "expected an Ipo object" );
1351
1352                 ipo = Ipo_FromPyObject( value );
1353
1354                 if( !ipo )
1355                         return EXPP_ReturnIntError( PyExc_RuntimeError,
1356                                                 "null ipo!" );
1357
1358                 if( ipo->blocktype != ID_LA )
1359                         return EXPP_ReturnIntError( PyExc_TypeError,
1360                                                 "Ipo is not a lamp data Ipo" );
1361         }
1362
1363         /* if already linked to Ipo, delete link */
1364
1365         if ( oldipo ) {
1366                 id = &oldipo->id;
1367                 if( id->us > 0 )
1368                         id->us--;
1369         }
1370
1371         /* assign new Ipo and increment user count, or set to NULL if deleting */
1372
1373         self->lamp->ipo = ipo;
1374         if ( ipo ) {
1375                 id = &ipo->id;
1376                 id->us++;
1377         }
1378
1379         return 0;
1380 }
1381
1382 /*
1383  * Lamp_insertIpoKey()
1384  *  inserts Lamp IPO key for RGB,ENERGY,SPOTSIZE,OFFSET,SIZE
1385  */
1386
1387 static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args )
1388 {
1389         int key = 0, map;
1390
1391         if( !PyArg_ParseTuple( args, "i", &( key ) ) )
1392                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1393                                                                                 "expected int argument" ) );
1394
1395         map = texchannel_to_adrcode(self->lamp->texact);
1396
1397         if (key == IPOKEY_RGB ) {
1398                 insertkey((ID *)self->lamp,LA_COL_R);
1399                 insertkey((ID *)self->lamp,LA_COL_G);
1400                 insertkey((ID *)self->lamp,LA_COL_B);      
1401         }
1402         if (key == IPOKEY_ENERGY ) {
1403                 insertkey((ID *)self->lamp,LA_ENERGY);    
1404         }       
1405         if (key == IPOKEY_SPOTSIZE ) {
1406                 insertkey((ID *)self->lamp,LA_SPOTSI);    
1407         }
1408         if (key == IPOKEY_OFFSET ) {
1409                 insertkey((ID *)self->lamp, map+MAP_OFS_X);
1410                 insertkey((ID *)self->lamp, map+MAP_OFS_Y);
1411                 insertkey((ID *)self->lamp, map+MAP_OFS_Z);  
1412         }
1413         if (key == IPOKEY_SIZE ) {
1414                 insertkey((ID *)self->lamp, map+MAP_SIZE_X);
1415                 insertkey((ID *)self->lamp, map+MAP_SIZE_Y);
1416                 insertkey((ID *)self->lamp, map+MAP_SIZE_Z);  
1417         }
1418
1419         allspace(REMAKEIPO, 0);
1420         EXPP_allqueue(REDRAWIPO, 0);
1421         EXPP_allqueue(REDRAWVIEW3D, 0);
1422         EXPP_allqueue(REDRAWACTION, 0);
1423         EXPP_allqueue(REDRAWNLA, 0);
1424
1425         return EXPP_incr_ret( Py_None );
1426 }
1427
1428 static PyObject *Lamp_getModesConst( void )
1429 {
1430         PyObject * attr = Py_BuildValue
1431                         ( "{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
1432                           "Shadows", EXPP_LAMP_MODE_SHADOWS, "Halo",
1433                           EXPP_LAMP_MODE_HALO, "Layer", EXPP_LAMP_MODE_LAYER,
1434                           "Quad", EXPP_LAMP_MODE_QUAD, "Negative",
1435                           EXPP_LAMP_MODE_NEGATIVE, "OnlyShadow",
1436                           EXPP_LAMP_MODE_ONLYSHADOW, "Sphere",
1437                           EXPP_LAMP_MODE_SPHERE, "Square",
1438                           EXPP_LAMP_MODE_SQUARE, "NoDiffuse",
1439                           EXPP_LAMP_MODE_NODIFFUSE, "NoSpecular",
1440                           EXPP_LAMP_MODE_NOSPECULAR );
1441
1442         if( !attr )
1443                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1444                                       "couldn't get Lamp.Modes attribute" );
1445
1446         return attr;
1447 }
1448
1449 static PyObject *Lamp_getTypesConst( void )
1450 {
1451         PyObject *attr = Py_BuildValue( "{s:h,s:h,s:h,s:h,s:h,s:h}",
1452                                       "Lamp", EXPP_LAMP_TYPE_LAMP,
1453                                       "Sun", EXPP_LAMP_TYPE_SUN,
1454                                       "Spot", EXPP_LAMP_TYPE_SPOT,
1455                                       "Hemi", EXPP_LAMP_TYPE_HEMI, 
1456                                       "Area", EXPP_LAMP_TYPE_AREA, 
1457                                       "Photon", EXPP_LAMP_TYPE_YF_PHOTON );
1458
1459         if( !attr )
1460                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1461                                       "couldn't get Lamp.Types attribute" );
1462
1463         return attr;
1464 }
1465
1466 static PyObject *Lamp_getUsers( BPy_Lamp * self )
1467 {
1468         return PyInt_FromLong( self->lamp->id.us );
1469 }
1470
1471 /* #####DEPRECATED###### */
1472
1473 static PyObject *Lamp_oldsetName( BPy_Lamp * self, PyObject * args )
1474 {
1475         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setName );
1476 }
1477
1478 static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args )
1479 {
1480         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSamples );
1481 }
1482
1483 static PyObject *Lamp_oldsetBufferSize( BPy_Lamp * self, PyObject * args )
1484 {
1485         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setBufferSize );
1486 }
1487
1488 static PyObject *Lamp_oldsetHaloStep( BPy_Lamp * self, PyObject * args )
1489 {
1490         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setHaloStep );
1491 }
1492
1493 static PyObject *Lamp_oldsetEnergy( BPy_Lamp * self, PyObject * args )
1494 {
1495         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setEnergy );
1496 }
1497
1498 static PyObject *Lamp_oldsetDist( BPy_Lamp * self, PyObject * args )
1499 {
1500         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setDist );
1501 }
1502
1503 static PyObject *Lamp_oldsetSpotSize( BPy_Lamp * self, PyObject * args )
1504 {
1505         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSpotSize );
1506 }
1507
1508 static PyObject *Lamp_oldsetSpotBlend( BPy_Lamp * self, PyObject * args )
1509 {
1510         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSpotBlend );
1511 }
1512
1513 static PyObject *Lamp_oldsetClipStart( BPy_Lamp * self, PyObject * args )
1514 {
1515         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setClipStart );
1516 }
1517
1518 static PyObject *Lamp_oldsetClipEnd( BPy_Lamp * self, PyObject * args )
1519 {
1520         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setClipEnd );
1521 }
1522
1523 static PyObject *Lamp_oldsetBias( BPy_Lamp * self, PyObject * args )
1524 {
1525         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setBias );
1526 }
1527
1528 static PyObject *Lamp_oldsetSoftness( BPy_Lamp * self, PyObject * args )
1529 {
1530         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSoftness );
1531 }
1532
1533 static PyObject *Lamp_oldsetHaloInt( BPy_Lamp * self, PyObject * args )
1534 {
1535         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setHaloInt );
1536 }
1537
1538 static PyObject *Lamp_oldsetQuad1( BPy_Lamp * self, PyObject * args )
1539 {
1540         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setQuad1 );
1541 }
1542
1543 static PyObject *Lamp_oldsetQuad2( BPy_Lamp * self, PyObject * args )
1544 {
1545         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setQuad2 );
1546 }
1547
1548 static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args )
1549 {
1550         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setIpo );
1551 }
1552
1553 static PyObject *Lamp_oldsetCol( BPy_Lamp * self, PyObject * args )
1554 {
1555         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setCol );
1556 }
1557
1558 /* 
1559  * the "not-well-behaved" methods which require more processing than 
1560  * just the simple wrapper
1561  */
1562
1563 /*
1564  * clearIpo() returns True/False depending on whether lamp has an Ipo
1565  */
1566
1567 static PyObject *Lamp_clearIpo( BPy_Lamp * self )
1568 {
1569         /* if Ipo defined, delete it and return true */
1570
1571         if( self->lamp->ipo ) {
1572                 PyObject *value = Py_BuildValue( "(O)", Py_None );
1573                 EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setIpo );
1574                 Py_DECREF ( value );
1575                 return EXPP_incr_ret_True();
1576         }
1577         return EXPP_incr_ret_False(); /* no ipo found */
1578 }
1579
1580 /*
1581  * setType() accepts a string while mode setter takes an integer
1582  */
1583
1584 static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * args )
1585 {
1586         char *type;
1587         PyObject *value, *error;
1588
1589         /* parse string argument */
1590
1591         if( !PyArg_ParseTuple( args, "s", &type ) )
1592                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1593                                                 "expected string argument" ) );
1594
1595         /* check for valid arguments, set type accordingly */
1596
1597         if( !strcmp( type, "Lamp" ) )
1598                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_LAMP;
1599         else if( !strcmp( type, "Sun" ) )
1600                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_SUN;
1601         else if( !strcmp( type, "Spot" ) )
1602                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_SPOT;
1603         else if( !strcmp( type, "Hemi" ) )
1604                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_HEMI;
1605         else if( !strcmp( type, "Area" ) )
1606                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_AREA;
1607         else if( !strcmp( type, "Photon" ) )
1608                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_YF_PHOTON;
1609         else
1610                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1611                                                 "unknown lamp type" );
1612
1613         /* build tuple, call wrapper */
1614
1615         value = Py_BuildValue( "(i)", type );
1616         error = EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setType );
1617         Py_DECREF ( value );
1618         return error;
1619 }
1620
1621 /*
1622  * setMode() accepts up to ten strings while mode setter takes an integer
1623  */
1624
1625 static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args )
1626 {
1627         short i, flag = 0;
1628         PyObject *error, *value;
1629         char *name;
1630
1631         /* check that we're passed a tuple of no more than 10 args*/
1632
1633         if ( !PyTuple_Check( args ) || PyTuple_Size( args ) > 10 )
1634                 return EXPP_ReturnPyObjError ( PyExc_AttributeError,
1635                                         "expected up to 10 string arguments" );
1636
1637         /* check each argument for type, find its value */
1638
1639         for ( i = PyTuple_Size( args ); i-- ; ) {
1640                 name = PyString_AsString ( PySequence_Fast_GET_ITEM( args, i ) );
1641                 if( !name )
1642                         return EXPP_ReturnPyObjError ( PyExc_AttributeError,
1643                                         "expected string argument" );
1644
1645                 if( !strcmp( name, "Shadows" ) )
1646                         flag |= ( short ) EXPP_LAMP_MODE_SHADOWS;
1647                 else if( !strcmp( name, "Halo" ) )
1648                         flag |= ( short ) EXPP_LAMP_MODE_HALO;
1649                 else if( !strcmp( name, "Layer" ) )
1650                         flag |= ( short ) EXPP_LAMP_MODE_LAYER;
1651                 else if( !strcmp( name, "Quad" ) )
1652                         flag |= ( short ) EXPP_LAMP_MODE_QUAD;
1653                 else if( !strcmp( name, "Negative" ) )
1654                         flag |= ( short ) EXPP_LAMP_MODE_NEGATIVE;
1655                 else if( !strcmp( name, "OnlyShadow" ) )
1656                         flag |= ( short ) EXPP_LAMP_MODE_ONLYSHADOW;
1657                 else if( !strcmp( name, "Sphere" ) )
1658                         flag |= ( short ) EXPP_LAMP_MODE_SPHERE;
1659                 else if( !strcmp( name, "Square" ) )
1660                         flag |= ( short ) EXPP_LAMP_MODE_SQUARE;
1661                 else if( !strcmp( name, "NoDiffuse" ) )
1662                         flag |= ( short ) EXPP_LAMP_MODE_NODIFFUSE;
1663                 else if( !strcmp( name, "NoSpecular" ) )
1664                         flag |= ( short ) EXPP_LAMP_MODE_NOSPECULAR;
1665                 else
1666                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
1667                                                         "unknown lamp flag argument" );
1668         }
1669
1670         /* build tuple, call wrapper */
1671
1672         value = Py_BuildValue( "(i)", flag );
1673         error = EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setMode );
1674         Py_DECREF ( value );
1675         return error;
1676 }
1677