inlets = 1;
outlets = 1;

// global sketch object
var jsketch;
var spkrmode = 0; // 0 == cartesian, 1 == spherical
var spkrcount = 0;
var spkrchans = new Array();
var spkrlocs = new Array();
var spkrgains = new Array();
var initDone = false;

function init()
{
    if (!initDone) {
        jsketch = new JitterObject("jit.gl.sketch","loudspeakers");
        jsketch.lighting_enable = 1;
        jsketch.smooth_shading = 0;
        initDone = true;
    }
}

function set_spkr_mode(m)
{
    if (m == 0) {
        spkrmode = 0;
    }
    else {
        spkrmode = 1;
    }
}

function set_spkrs() 
{
    // expects interlaced list of speaker chan and speaker locations in multiples of 3 (cartesian or spherical coords): 
    //      <chan> <location>...
    var locs = arrayfromargs(arguments);
    var listsize;
    
    // check that list is multiple of 4 (chans + 3D coords)
    var remainder = (locs.length) % 4;
    if (remainder != 0) {
        listsize = (locs.length) - remainder;
        post("Message length incorrect. Truncating accordingly.");
    }
    else {
        listsize = locs.length;
    }
    
    // set spkrcount
    spkrcount = listsize / 4;
    
    // clear spkrchans array, if necessary
    if (spkrchans.length) {
        spkrchans.splice(0, spkrchans.length);
    }
    
    // clear spkrlocs array, if necessary
    if (spkrlocs.length) {
        spkrlocs.splice(0, spkrlocs.length);
    }
    
    // populate spkrchans and spkrlocs arrays with incoming list
    // if cartesian
    if (spkrmode == 0) {
        for (var i = 0; i < listsize; i+=4) {
            spkrchans.push(locs[i]);
            spkrlocs.push(locs[i+1]);
			spkrlocs.push(locs[i+2]);
			spkrlocs.push(-locs[i+3]);
        }
    }
    // if spherical, convert to cartesian
    else {
        var az, el;
        for (var i = 0; i < listsize; i+=4) {
            spkrchans.push(locs[i]);
            az = (locs[i+1] / 180.) * 3.141593;
            el = (locs[i+2] / 180.) * 3.141593;
            spkrlocs.push(Math.sin(az) * (Math.cos(el) * locs[i+3])); // x
            spkrlocs.push(Math.sin(el) * locs[i+3]); // y
            spkrlocs.push(-1.0 * (Math.cos(az) * (Math.cos(el) * locs[i+3]))); // z
        }    
    }
    
    // clear spkrgains array, if necessary
    if (spkrgains.length) {
        spkrgains.splice(0, spkrgains.length);
    }
    
    // size spkrgains array to spkrcount and initialize gains to 0.
    for (var i = 0; i < spkrcount; i++) {
        spkrgains.push(0.0);
    }
}

// check to see if chan exists, return index val if found, else -1
function hasChan(ch)
{
    for (var i = 0; i < spkrcount; i++) {
        if (spkrchans[i] == ch) {
            return i;
        }
    }
    
    return -1;
}

function bang()
{    
    if (!initDone) {
        jsketch = new JitterObject("jit.gl.sketch","loudspeakers");
        jsketch.lighting_enable = 1;
        jsketch.smooth_shading = 0;
        initDone = true;
    }
        
    jsketch.reset();
    
    var count = 0;
    for (var i = 0; i < spkrlocs.length; i+=3, count++) {
        jsketch.glcolor(spkrgains[count] * 2.0, (1.0 - spkrgains[count]) * 0.5, (1.0 - spkrgains[count]) * 0.5, 1.);
        jsketch.moveto(spkrlocs[i], spkrlocs[i+1], spkrlocs[i+2]);
        jsketch.cube(0.05 + (spkrgains[count] * 0.1));    
    }
}

function draw_spkrs()
{
    var gains = arrayfromargs(arguments);
    var listsize;
    
    // check that list is multiple of 2 (chan + gain)
    var remainder = (gains.length) % 2;
    if (remainder != 0) {
        listsize = (gains.length) - remainder;
        //post("Message length incorrect. Truncating accordingly.");
    }
    else {
        listsize = gains.length;
    }
    
    // set spkrgains to 0.
    for (var i = 0; i < spkrcount; i++) {
        spkrgains[i] = 0.0;
    }
    
    var chanID = -1;
    for (var i = 0; i < listsize; i+=2) {
        chanID = hasChan(gains[i]);
        if (chanID != -1) {
            spkrgains[chanID] = gains[i+1];
        }
    }  
    
    if (!initDone) {
        jsketch = new JitterObject("jit.gl.sketch","loudspeakers");
        jsketch.lighting_enable = 1;
        jsketch.smooth_shading = 0;
        initDone = true;
    }
        
    jsketch.reset();
    
    var count = 0;
    for (var i = 0; i < spkrlocs.length; i+=3, count++) {
        jsketch.glcolor(spkrgains[count] * 2.0, (1.0 - spkrgains[count]) * 0.5, (1.0 - spkrgains[count]) * 0.5, 1.);
        jsketch.moveto(spkrlocs[i], spkrlocs[i+1], spkrlocs[i+2]);
        jsketch.cube(0.05 + (spkrgains[count] * 0.1));    
    }
}