QScriptValue ScriptRunner::writeFile(QScriptContext *context, QScriptEngine *engine)
{
    ScriptRunner * me = (ScriptRunner *) engine->parent();
    QScriptValue error;
    if (!me->argCount(context, error, 2))
        return error;
    QScriptValue path_value = context->argument(0);
    if (!me->maybeThrowArgumentError(context, error, path_value.isString()))
        return error;
    QScriptValue contents_value = context->argument(1);
    if (!me->maybeThrowArgumentError(context, error, contents_value.isString()))
        return error;

    QString path = path_value.toString();
    QFile file(path);
    if (!file.open(QIODevice::WriteOnly))
        return context->throwError(tr("Unable to write file: %1").arg(path));
    QByteArray contents = contents_value.toString().toUtf8();
    int index = 0;
    while (index < contents.size()) {
        int written_size = file.write(contents.mid(index));
        if (written_size == -1) {
            file.close();
            return context->throwError(tr("Unable to write file: %1").arg(path));
        }
        index += written_size;
    }
    file.close();
    return QScriptValue();
}
QScriptValue ScriptRunner::currentTimestamp(QScriptContext *context, QScriptEngine *engine)
{
    ScriptRunner * me = (ScriptRunner *) engine->parent();
    QScriptValue error;
    if (!me->argCount(context, error, 0))
        return error;
    return QScriptValue((double)QDateTime::currentMSecsSinceEpoch());
}
int main(int argc, char** argv)
{
	Render render;
	ScriptRunner * sr = ScriptRunner::getInstance();
	Logger * logger = Logger::getInstance();
	osg::ArgumentParser parser = osg::ArgumentParser(&argc, argv);
	string filename; // filename for script 
	

	if(parser.containsOptions()){
		//grabs the file name that is associated with the --script 
	parser.read("--script",filename);
		ifstream infile;
		infile.open(filename);
		sr->setActions(sr->parseScript(infile));
	}           
	/*
	if(parser.containsOptions()){
		int sLoc = parser.find("-s");
		int aLoc = parser.find("-a");
		int lLoc = parser.find("-l");
		if(sLoc > 0){
			if(parser.isString(sLoc+1)){
				std::ifstream infile;
				infile.open(parser[sLoc+1]);
				sr->setActions(sr->parseScript(infile));
				std::cout << parser[sLoc+1] << std::endl;
			 }
		}
		if(aLoc > 0){
			if(parser.isString(aLoc+1)){
				std::cout << parser[aLoc+1] << std::endl;
				std::ifstream infile;
				infile.open(parser[aLoc+1]);
				Constants::setConstantsFromFile(infile);
				std::cout << Constants::getInstance()->gravity << std::endl;
			 }
		}
		if(lLoc > 0)
		{
			if(parser.isString(lLoc+1))
			{
				logger->setFileName(parser[lLoc+1]);
			}
		}
		else
			{
				logger->setFileName("helicopterLog.txt");
			}
	}
	*/
	render.Game_Play();
	return 0;
}
QScriptValue ScriptRunner::args(QScriptContext *context, QScriptEngine *engine)
{
    ScriptRunner * me = (ScriptRunner *) engine->parent();
    QScriptValue error;
    if (!me->argCount(context, error, 0))
        return error;

    QScriptValue array = engine->newArray();
    foreach (QString arg, me->m_args)
        array.property("push").call(array, QScriptValueList() << arg);
    return array;
}
QScriptValue ScriptRunner::setInterval(QScriptContext *context, QScriptEngine *engine)
{
    ScriptRunner * me = (ScriptRunner *) engine->parent();
    QScriptValue error;
    if (!me->argCount(context, error, 2))
        return error;
    QScriptValue func = context->argument(0);
    if (!me->maybeThrowArgumentError(context, error, func.isFunction()))
        return error;
    QScriptValue ms = context->argument(1);
    if (!me->maybeThrowArgumentError(context, error, ms.isNumber()))
        return error;

    return me->setTimeout(func, ms.toInt32(), context->parentContext()->thisObject(), true);
}
QScriptValue ScriptRunner::readFile(QScriptContext *context, QScriptEngine *engine)
{
    ScriptRunner * me = (ScriptRunner *) engine->parent();
    QScriptValue error;
    if (!me->argCount(context, error, 1))
        return error;
    QScriptValue path_value = context->argument(0);
    if (!me->maybeThrowArgumentError(context, error, path_value.isString()))
        return error;

    QString path = path_value.toString();
    QString contents = me->internalReadFile(path);
    if (contents.isNull())
        return QScriptValue();
    return contents;
}
QScriptValue ScriptRunner::clearTimeout(QScriptContext *context, QScriptEngine *engine)
{
    ScriptRunner * me = (ScriptRunner *) engine->parent();
    QScriptValue error;
    if (!me->argCount(context, error, 1))
        return error;
    QScriptValue id = context->argument(0);
    if (!me->maybeThrowArgumentError(context, error, id.isNumber()))
        return error;

    int int_id = id.toInt32();
    QTimer * ptr = me->m_timer_ptrs.value(int_id, NULL);
    me->m_timer_ptrs.remove(int_id);
    me->m_script_timers.remove(ptr);
    delete ptr;
    return QScriptValue();
}
void ScriptWidget::RunScript()
{
	//Get the current state of the inventory.
	emit SaveToInventoryTag();

	//Run script on inventory.
	consoleTextEdit->clear();
	const string scriptString = scriptTextEdit->toPlainText().toStdString();
	
	ScriptRunner scriptRunner;
	if(!scriptRunner.Run(inventoryTag,scriptString))
	{
		consoleTextEdit->append(scriptRunner.Output().c_str());
		consoleTextEdit->append(scriptRunner.Error().c_str());
		return;
	}
	consoleTextEdit->append(scriptRunner.Output().c_str());
	consoleTextEdit->append("<b>Done.</b>");

	//Sync changes to rest of program.
	emit ReloadFromInventoryTag();
}
void Render::Game_Play(){
	crash = false;
	friction = true;
	missileCollison = false;
	fireTimer=Constants::getInstance()->fireRate;

	//hud
	hud.initializeHudText();
	osg::Camera * hudCamera;

	ScriptRunner * sr = ScriptRunner::getInstance();
	sr->setRender(this);
	osg::ref_ptr<osg::Node> helicopter = osgDB::readNodeFile("Sikorsky2.osg");
	osg::ref_ptr<osg::Node> ground = osgDB::readNodeFile("lz.osg");
	osg::ref_ptr<osg::Node> flycow = osgDB::readNodeFile("cow.osg");

	ball1  = new osg::ShapeDrawable;
	ball1->setShape( new osg::Sphere(osg::Vec3(0.0f, 0.0f,0.0f), 25.0f));
	ball1->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
	osg::ref_ptr<osg::Geode> ball1Node = new osg::Geode;
	ball1Node->addDrawable(ball1.get());

	ball2  = new osg::ShapeDrawable;
	ball2->setShape( new osg::Sphere(osg::Vec3(0.0f, 0.0f,0.0f), 25.0f));
	ball2->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
	osg::ref_ptr<osg::Geode> ball2Node = new osg::Geode;
	ball2Node->addDrawable(ball2.get());

	ball3  = new osg::ShapeDrawable;
	ball3->setShape( new osg::Sphere(osg::Vec3(0.0f, 0.0f,0.0f), 25.0f));
	ball3->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
	osg::ref_ptr<osg::Geode> ball3Node = new osg::Geode;
	ball3Node->addDrawable(ball3.get());

	tor1Tr = new osg::PositionAttitudeTransform;
	tor2Tr = new osg::PositionAttitudeTransform;
	tor3Tr = new osg::PositionAttitudeTransform;

	tor1Tr->addChild(ball1Node.get());
	tor2Tr->addChild(ball2Node.get());
	tor3Tr->addChild(ball3Node.get());

	tor1Tr->setPosition(osg::Vec3(0.0f, -200.0f, 80.0f));
	tor2Tr->setPosition(osg::Vec3(10.0f, -300.0f, 70.0f));
	tor3Tr->setPosition(osg::Vec3(20.0f, -400.0f, 60.0f));

	osg::ref_ptr<osg::Group> torusGroup = new osg::Group();
	torusGroup->addChild(tor1Tr);
	torusGroup->addChild(tor2Tr);
	torusGroup->addChild(tor3Tr);

	helicopterTransform = new osg::PositionAttitudeTransform;
	helicopterTransform->addChild(helicopter.get());
	helicopterTransform->setPosition(osg::Vec3(0.0f, 0.0f, 0.0f));
	helicopterTransform->setAttitude(osg::Quat((0), osg::Vec3d(1.0, 0.0, 0.0)));

	
	// rotate model
	helicopterTransform->setAttitude( 	 	
		osg::Quat( 	 	
			osg::DegreesToRadians(90.0f),osg::Vec3f(1,0,0), 	 	
	        osg::DegreesToRadians(0.0f),osg::Vec3f(0,0,1), 	 	
	        osg::DegreesToRadians(0.0f),osg::Vec3f(0,1,0) 	 	
	        ) 	 	
	);

	osg::ref_ptr<ModelController> ctrler = new ModelController(helicopterTransform.get(),this);

	groundTransform = new osg::PositionAttitudeTransform;
	groundTransform->addChild(ground.get());
	groundTransform->setPosition(osg::Vec3(0.0f, 0.0f, -100.0f));
	groundTransform->setScale(osg::Vec3(30.0f, 30.0f, 1.0f));

	modelPosition.set(helicopterTransform->getPosition());
	modelVelocity.set(osg::Vec3f(0,0,0));

	helicopterThrust = osg::Vec3f(0.0, 0.0, 0.0);

	
	// missile
	cowTransform = new osg::PositionAttitudeTransform;
	cowTransform->addChild(flycow.get());
	cowTransform->setPosition(modelPosition);
	cowTransform->setScale(osg::Vec3(0.3f, 0.3f, 0.3f));
	cowPosition.set(helicopterTransform->getPosition());
	cowVelocity.set(osg::Vec3f(0,0,0));
	fire = false; // default missile setting
	

	//hud
	hudCamera = hud.getHudCamera();
	
	osg::ref_ptr<osg::Group> rootNode = new osg::Group;  //Create a group node
	rootNode->addChild( groundTransform.get());
	rootNode->addChild( helicopterTransform.get());
	rootNode->addChild( cowTransform.get());
	rootNode->addChild(torusGroup.get());


	//hud
	rootNode->addChild(hudCamera);
	
	viewer.addEventHandler( ctrler.get());

	viewer.addEventHandler(new TimerHandler(this));	

	viewer.setUpViewInWindow(50,50,1024,768);

	viewer.setSceneData( rootNode.get());

	//This bit of code will have the camera follow the model
    osg::ref_ptr<osgGA::NodeTrackerManipulator> nodeTracker = new osgGA::NodeTrackerManipulator;
    nodeTracker->setHomePosition( osg::Vec3(0.0, 100.0, 0),
                                    osg::Vec3(), osg::Z_AXIS );
    //This will track the center of the helicopter and rotate as well.
    nodeTracker->setTrackerMode( osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION );
    nodeTracker->setRotationMode( osgGA::NodeTrackerManipulator::TRACKBALL );
    nodeTracker->setTrackNode( helicopter );
    viewer.setCameraManipulator( nodeTracker );


	last = 0;
	viewer.run();
}
void Render::Game_Play(){
	ScriptRunner * sr = ScriptRunner::getInstance();
	sr->setRender(this);
	osg::ref_ptr<osg::Node> helicopter = osgDB::readNodeFile("Sikorsky2.osg");
	osg::ref_ptr<osg::Node> ground = osgDB::readNodeFile("lz.osg");
	osg::ref_ptr<osg::Node> confetti = osgDB::readNodeFile("glsl_confetti.osgt");
	//osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg");
	osg::ref_ptr<osg::Node> dumpTruck = osgDB::readNodeFile("dumptruck.osg");
	osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg");
	osg::ref_ptr<osg::Node> spaceShip = osgDB::readNodeFile("spaceShip.osgt");
	
	
	ball1  = new osg::ShapeDrawable;
	ball1->setShape( new osg::Sphere(osg::Vec3(0.0f, 0.0f,0.0f), 25.0f));
	ball1->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
	osg::ref_ptr<osg::Geode> ball1Node = new osg::Geode;
	ball1Node->addDrawable(ball1.get());

	ball2  = new osg::ShapeDrawable;
	ball2->setShape( new osg::Sphere(osg::Vec3(0.0f, 0.0f,0.0f), 25.0f));
	ball2->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
	osg::ref_ptr<osg::Geode> ball2Node = new osg::Geode;
	ball2Node->addDrawable(ball2.get());

	ball3  = new osg::ShapeDrawable;
	ball3->setShape( new osg::Sphere(osg::Vec3(0.0f, 0.0f,0.0f), 25.0f));
	ball3->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
	osg::ref_ptr<osg::Geode> ball3Node = new osg::Geode;
	ball3Node->addDrawable(ball3.get());
	
	tor1Tr = new osg::PositionAttitudeTransform;
	tor2Tr = new osg::PositionAttitudeTransform;
	tor3Tr = new osg::PositionAttitudeTransform;

	tor1Tr->addChild(ball1Node.get());
	tor2Tr->addChild(ball2Node.get());
	tor3Tr->addChild(ball3Node.get());

	tor1Tr->setPosition(osg::Vec3(0.0f, -200.0f, 80.0f));
	tor2Tr->setPosition(osg::Vec3(10.0f, -300.0f, 70.0f));
	tor3Tr->setPosition(osg::Vec3(20.0f, -400.0f, 60.0f));

	osg::ref_ptr<osg::Group> torusGroup = new osg::Group();
	torusGroup->addChild(tor1Tr);
	torusGroup->addChild(tor2Tr);
	torusGroup->addChild(tor3Tr);
	

	helicopterTransform = new osg::PositionAttitudeTransform;
	helicopterTransform->addChild(helicopter.get());
	helicopterTransform->setPosition(osg::Vec3(0.0f, 0.0f, 0.0f));
	helicopterTransform->setAttitude(osg::Quat((3.14/2), osg::Vec3d(1.0, 0.0, 0.0)));

	osg::ref_ptr<ModelController> ctrler = new ModelController(helicopterTransform.get(),this);

	groundTransform = new osg::PositionAttitudeTransform;
	groundTransform->addChild(ground.get());
	groundTransform->setPosition(osg::Vec3(0.0f, 0.0f, -100.0f));
	groundTransform->setScale(osg::Vec3(30.0f, 30.0f, 1.0f));
	/*
	osg::ref_ptr<osg::PositionAttitudeTransform> confettiTransform = new osg::PositionAttitudeTransform;
	confettiTransform->addChild(confetti.get());
	confettiTransform->setPosition(osg::Vec3(-150.0f,-2500.0f,100));
	confettiTransform->setScale(osg::Vec3(100.0f,100.0f,100.0f));

	osg::ref_ptr<osg::PositionAttitudeTransform> cowTransform = new osg::PositionAttitudeTransform;
	cowTransform->addChild(cow.get());
	cowTransform->setPosition(osg::Vec3(100.0f, -1500.0f, 50.0f));
	cowTransform->setScale(osg::Vec3(20.0f, 20.0f, 20.0f));
*/

	
	osg::ref_ptr<osg::PositionAttitudeTransform> dumpTruckTransform = new osg::PositionAttitudeTransform;
	dumpTruckTransform->addChild(dumpTruck.get());
	dumpTruckTransform->setPosition(osg::Vec3(600.0f,-4000.0f,500));
	dumpTruckTransform->setScale(osg::Vec3(50.0f,50.0f,50.0f));

	osg::ref_ptr<osg::PositionAttitudeTransform> cowTransform = new osg::PositionAttitudeTransform;
	cowTransform->addChild(cow.get());
	cowTransform->setPosition(osg::Vec3(0.0f, -2000.0f, 700.0f));
	cowTransform->setScale(osg::Vec3(60.0f, 60.0f, 60.0f));

	osg::ref_ptr<osg::PositionAttitudeTransform> spaceShipTransform = new osg::PositionAttitudeTransform;
	spaceShipTransform->addChild(spaceShip.get());
	spaceShipTransform->setPosition(osg::Vec3(700.0f,-7000.0f, 1000.0f));
	spaceShipTransform->setScale(osg::Vec3(70.0f,70.0f,70.0f));

	
	modelPosition.set(helicopterTransform->getPosition());
	modelVelocity.set(osg::Vec3f(0,0,0));

	helicopterThrust = osg::Vec3f(0.0, 0.0, 0.0);

	/*
	osg::ref_ptr<osg::Group> rootNode = new osg::Group;  //Create a group node
	rootNode->addChild( groundTransform.get());
	rootNode->addChild( helicopterTransform.get());
	rootNode->addChild(torusGroup.get());
	rootNode->addChild( confettiTransform.get());
	rootNode->addChild( cowTransform.get());
	*/
	osg::ref_ptr<osg::Group> rootNode = new osg::Group;  //Create a group node
	rootNode->addChild( groundTransform.get());
	rootNode->addChild( helicopterTransform.get());
	rootNode->addChild( torusGroup.get());
	rootNode->addChild( spaceShipTransform.get());
	rootNode->addChild( dumpTruckTransform.get());
	rootNode->addChild( cowTransform.get());
	
	viewer.addEventHandler( ctrler.get());

	viewer.addEventHandler(new TimerHandler(this));	

	viewer.setUpViewInWindow(100,100,800,600);

	viewer.setSceneData( rootNode.get());

	//This bit of code will have the camera follow the model
    osg::ref_ptr<osgGA::NodeTrackerManipulator> nodeTracker = new osgGA::NodeTrackerManipulator;
    nodeTracker->setHomePosition( osg::Vec3(0, 100.0, 0),
                                    osg::Vec3(), osg::Z_AXIS );
    //This will track the center of the helicopter and rotate as well.
    nodeTracker->setTrackerMode( osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION );
    nodeTracker->setRotationMode( osgGA::NodeTrackerManipulator::TRACKBALL );
    nodeTracker->setTrackNode( helicopter );
    viewer.setCameraManipulator( nodeTracker );


	last = 0;
	viewer.run();
}