/**
 *
 *  You can modify and use this source freely
 *  only for the development of application related Live2D.
 *
 *  (c) Live2D Inc. All rights reserved.
 */
#include "SampleLive2DSprite.h"
#include "base/CCDirector.h"
#include "util/UtSystem.h"

#include "graphics/DrawProfileCocos2D.h"
#include "platform/CCFileUtils.h"

using namespace live2d;
USING_NS_CC;


const char* TEXTURES[] ={
	"epsilon/Epsilon2.1.2048/texture_00.png" ,
	NULL
} ;
SampleLive2DSprite::SampleLive2DSprite()
: models()
{
}

SampleLive2DSprite::~SampleLive2DSprite()
{
	for (int i = 0; i < NUM_MODELS; i++)
	{
		delete models[i];
	}

	// テクスチャを解放
	Director::getInstance()->getTextureCache()->removeTextureForKey(std::string(TEXTURES[0]));
	
	delete motionMgr;
	delete motion;
}

bool SampleLive2DSprite::init()
{
	if (DrawNode::init())
	{
		if (models[0] != nullptr)
		{
			for (int i = 0; i < NUM_MODELS; i++)
			{
				delete models[i];
				models[i] = nullptr;
			}
		}
		
		const char* MODEL = "epsilon/Epsilon2.1.moc" ;

		const char* MOTION_PATH = "epsilon/Epsilon2.1_idle_01.mtn" ;

		for( int i = 0 ; TEXTURES[i] != NULL ; i++ ){

			auto texture =Director::getInstance()->getTextureCache()->addImage(std::string(TEXTURES[i]));		

			
			/*Texture2D::TexParams texParams = { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };
			texture->setTexParameters(texParams);
			texture->generateMipmap();*/

			int glTexNo = texture->getName() ;

			textures.push_back( texture ) ;
		}

		for (int i = 0; i < NUM_MODELS; i++)
		{
			unsigned char* buf;
			ssize_t bufSize;
			buf = FileUtils::getInstance()->getFileData(MODEL,"rb", &bufSize);
		
			auto live2DModel = Live2DModelOpenGL::loadModel( buf,bufSize ) ;
		
			delete[] buf;
		
			models[i]=live2DModel;

			for( int i = 0 ; TEXTURES[i] != NULL ; i++ ){	
				live2DModel->setTexture( i , textures[i]->getName() ) ;// テクスチャとモデルを結びつける
			}

			// Live2Dモデルはローカル座標で左上を原点にして(CanvasWidth、CanvasWidth)
			// のサイズになるため、以下のようにして調整してください。
			float w = Director::getInstance()->getWinSize().width;
			float h = Director::getInstance()->getWinSize().height;
			float scx = 2.0 / live2DModel->getCanvasWidth() ;
			float scy = -2.0 / live2DModel->getCanvasWidth() * (w/h);
			float d=1.0f/NUM_MODELS;
			float x = -1 +d*i;
			float y = 1 ;
			float matrix []= {
				scx , 0 , 0 , 0 ,
				0 , scy ,0 , 0 ,
				0 , 0 , 1 , 0 ,
				x , y , 0 , 1
			} ;
		
			live2DModel->setMatrix(matrix) ;// 位置を設定
		
			live2DModel->setPremultipliedAlpha( true );
		}

		

		unsigned char* buf;
		ssize_t bufSize;
		buf = FileUtils::getInstance()->getFileData(MOTION_PATH,"rb", &bufSize);

		motionMgr=new MotionQueueManager();
		motion=Live2DMotion::loadMotion(buf,bufSize);

		delete[] buf;
	}
	
	return true;
}

void SampleLive2DSprite::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
{
	DrawNode::draw(renderer, transform, flags);

	
	_customCommand.init(_globalZOrder);
	_customCommand.func = CC_CALLBACK_0(SampleLive2DSprite::onDraw, this, transform, flags);
	renderer->addCommand(&_customCommand);
}

void SampleLive2DSprite::onDraw(const cocos2d::Mat4 &transform, uint32_t flags)
{
	kmGLPushMatrix();
    kmGLLoadMatrix(&transform);
 
	if (motionMgr->isFinished())
	{
		motionMgr->startMotion(motion,false);
	} 
	
	// Live2Dの描画前と描画後に以下の関数を呼んでください
	// live2d::DrawProfileCocos2D::preDraw() ;
	// live2d::DrawProfileCocos2D::postDraw() ;
	// これはOpenGLの状態をもとに戻すための処理です。
	// これを行わない場合、Cocos2DかLive2Dどちらかで状態の不整合が起こります。
	live2d::DrawProfileCocos2D::preDraw();

	for (int i = 0; i < NUM_MODELS; i++)
	{
		auto live2DModel=models[i];
		motionMgr->updateParam(live2DModel);
		live2DModel->update() ;
		live2DModel->draw() ;
	}
	
	
	live2d::DrawProfileCocos2D::postDraw() ;

	kmGLPopMatrix();
}
SampleLive2DSprite* SampleLive2DSprite::createDrawNode()
{
	SampleLive2DSprite *ret = new SampleLive2DSprite();
	if (ret && ret->init())
	{
		ret->autorelease();
		return ret;
	}
	else
	{
		CC_SAFE_DELETE(ret);
		return nullptr;
	}


}
