//
// CheetahBullet package.
//
// 20110512: first

var VERSION = "1.0b8";

var simFile_ext = "chdata";

var targetCount = 5;

var toRAD = Math.PI/180;
var toDEG = 180/Math.PI;

function buildUI(obj) {
    
    obj.setParameter('name','CheetahBullet Particle Rep');
    
    obj.addParameterInt("frame", 0, 0, 1000000, true, true);
    obj.addParameterString("sim. file", "", true);
    obj.addParameterButton("set sim. file", "set", "setSimFile");
    obj.addParameterLink("sim. target", false);
    
    obj.addParameterSeparator("References");
    
    for (var i = 1;i <= targetCount;i++) {
        obj.addParameterLink("target "+i, false);
    }
}

function buildObject(obj) {
    
    //print('----');
    var frame = obj.getParameter("frame");
    var target = obj.getParameter("sim. target");
    var file = obj.getParameter("sim. file");
    
    if (!target) return;
    if (!file) return;
    
    
    var tmp = new File( file );
    tmp.open( READ_MODE, LITTLE_ENDIAN );
    
    if (! tmp.isOpen()) {
        print('sim. file does not exist');
        return;
    }
    
    // getting target
    var copyList = []
    for (var i = 1;i <= targetCount;i++) {
        var copyTarget = obj.getParameter("target "+i);
        if (copyTarget) {
            copyList.push( copyTarget.getParameter("name") );
        }
    }
    
    //print('--parsing sim. file [particle]');
    var i,j,k;
    var frame_total = tmp.readUInt();
    var info = [];
    
    //print( 'frame_total:'+frame_total );
    for (i = 0;i < frame_total;i++) {
        var f = tmp.readInt();
        var oc = tmp.readInt();
        var stride = tmp.readInt();
        
        if (frame != f) { // skip
            tmp.seek(stride, SEEK_CUR);
        } else {
            for (var j = 0;j < oc;j++) {
                var type = [];
                type[0] = tmp.readInt(); // index
                type[1] = tmp.readInt(); // rigid:0
                type[2] = tmp.readInt(); // particle index
                type[3] = tmp.readInt(); // particle total
                if (type[1] == 0) { // rigid
                    var mat = new Mat4D();
                    mat.m00 = tmp.readFloat(); mat.m10 = tmp.readFloat(); mat.m20 = tmp.readFloat(); mat.m30 = tmp.readFloat();
                    mat.m01 = tmp.readFloat(); mat.m11 = tmp.readFloat(); mat.m21 = tmp.readFloat(); mat.m31 = tmp.readFloat();
                    mat.m02 = tmp.readFloat(); mat.m12 = tmp.readFloat(); mat.m22 = tmp.readFloat(); mat.m32 = tmp.readFloat();
                    mat.m03 = tmp.readFloat(); mat.m13 = tmp.readFloat(); mat.m23 = tmp.readFloat(); mat.m33 = tmp.readFloat();
                    info.push( [ type, mat ] );
                } else if (type[1] == 1) { // soft
                    info.push( [ type, tmp.getpos() ] );
                    tmp.seek(type[2]*4*3, SEEK_CUR);
                } else if (type[1] == 2) { // particle
                    info.push( [ type, tmp.getpos() ] );
                    tmp.seek( 4*3 + 4*3, SEEK_CUR); // pos + rot
                } else if (type[1] == 3) { // spline
                    info.push( [ type, tmp.getpos() ] );
                    tmp.seek(type[2]*4*3, SEEK_CUR); // same as soft
                } else if (type[1] == 10) { // compound
                    var mat = new Mat4D();
                    mat.m00 = tmp.readFloat(); mat.m10 = tmp.readFloat(); mat.m20 = tmp.readFloat(); mat.m30 = tmp.readFloat();
                    mat.m01 = tmp.readFloat(); mat.m11 = tmp.readFloat(); mat.m21 = tmp.readFloat(); mat.m31 = tmp.readFloat();
                    mat.m02 = tmp.readFloat(); mat.m12 = tmp.readFloat(); mat.m22 = tmp.readFloat(); mat.m32 = tmp.readFloat();
                    mat.m03 = tmp.readFloat(); mat.m13 = tmp.readFloat(); mat.m23 = tmp.readFloat(); mat.m33 = tmp.readFloat();
                    info.push( [ type, mat ] );
                }
            }
            break;
        }
        if (tmp.getpos() >= tmp.size()) break;
    }
    
    /*
    print( 'info.length:'+info.length );
    for (i = 0;i < info.length;i++) {
        print(i+' ('+info[i]+')');
    }
     */
    
    var count = target.childCount();
    // target check and frame check
    if (target == undefined || info.length < 1) {
        return;
    }
    
    var core = obj.core();
    
    var infoIndex = 0;
    for (i = 0;i < count;i++) {
        var copy = target.childAtIndex(i);
        var copyName = copy.getParameter("name");
        if (info.length <= infoIndex) {
            print('wrong info [particle]');
            return;
        }
        // ignore other object
        if ( copy.family() != SPLINEFAMILY && copy.family() != PARTICLEFAMILY && copy.family() != NGONFAMILY && copy.type() != FOLDER) continue;
        if ( copy.getParameter("scriptName").indexOf("CheetahBullet Constraint.js") > -1 ) continue;
        //
        if ( copyList.indexOf( copyName ) == -1) {
            if (info[infoIndex][0][1] == 2) { // if particles
                infoIndex += info[infoIndex][0][3];
            } else {
                infoIndex++;
            }
            continue;
        }
        if (copy.family() == PARTICLEFAMILY) {
            if (info.length <= infoIndex) break; // error check.
            
            //print('--build [particle]');
            if (info[infoIndex][0][1] == 2) { // particle
                var particleCount = info[infoIndex][0][3];
                
                {
                    var copyCore = copy.core();
                    
                    if ( copyCore.particleCount() != particleCount ) {
                        print("particle count doesn't match."+copyCore.particleCount() + ' - '+particleCount);
                        break;
                    }
                    
                    for (pi = 0;pi < particleCount;pi++) {
                        tmp.setpos(info[infoIndex][1]);
                        
                        var cp = copyCore.particleAtIndex(pi);
                        var p = core.addParticle();
                        var pScale = cp.getScale();
                        p.setPosition( tmp.readFloat(), tmp.readFloat(), tmp.readFloat() );
                        p.setRotation( tmp.readFloat(), tmp.readFloat(), tmp.readFloat() );
                        p.setScale( pScale.x, pScale.y, pScale.z );
                        infoIndex++;
                    }
                }
            }
        }
    }
    tmp.close();
    
    if (core.particleCount() == 0) {
        var p = core.addParticle();
        p.setPosition( 0, 0, 0 );
    }
}

function setSimFile( obj ) {
    var simFile = OS.runOpenPanel(simFile_ext);
    
    if (simFile != null) {
        obj.setParameter("sim. file", simFile);
    }
}

function tagForScriptName(obj, scriptName) {
	var tagCount = obj.tagCount();
	var resultTag = false;
	for (var i = 0;i < tagCount;i++) {
		var tag = obj.tagAtIndex(i);
        var sn = tag.getParameter("scriptName");
		if (sn.indexOf(scriptName) != -1 && tag.getParameter("tagOn")) {
			resultTag = tag;
		}
	}
	return resultTag;
}

function Vec3D_toString( vec ) {
	return vec.x.toFixed(3) + ', ' + vec.y.toFixed(3) + ', ' + vec.z.toFixed(3);
}

function Mat4D_toString( mat ) {
    var str = '(' + mat.m00.toFixed(3) + ', ' + mat.m01.toFixed(3) + ', ' + mat.m02.toFixed(3) + ', ' + mat.m03.toFixed(3) + "\n";
    str += ' ' + mat.m10.toFixed(3) + ', ' + mat.m11.toFixed(3) + ', ' + mat.m12.toFixed(3) + ', ' + mat.m13.toFixed(3) + "\n";
    str += ' ' + mat.m20.toFixed(3) + ', ' + mat.m21.toFixed(3) + ', ' + mat.m22.toFixed(3) + ', ' + mat.m23.toFixed(3) + "\n";
    str += ' ' + mat.m30.toFixed(3) + ', ' + mat.m31.toFixed(3) + ', ' + mat.m32.toFixed(3) + ', ' + mat.m33.toFixed(3) + ")\n";
    return str; 
}

function printElapsedTime(label, time) {
	if (time/1000 > 60) {
		print( label + ':' + (time/1000).toFixed(2) + 'sec(s) ( ' + Math.floor(time/1000/60) + '.' + Math.floor((time/1000)%60) + ' )');
	} else {
		print( label + ':' + (time/1000).toFixed(2) + 'sec(s)' );
	}
}
