/*******************************************************************************
************************ Les bibliothèques à inclure ***************************
*******************************************************************************/
#include "main.h"

/* Surfaces */
void *background    = 0;    /**< Le fond de l'écran */
void *tree          = 0;    /**< Un arbre */
void *cloud         = 0;    /**< Un nuage */
void *flower        = 0;    /**< Une fleur et son mont */
void *ground        = 0;    /**< Le sol */
void *character     = 0;    /**< Le personnage */

/* Animations */
void *animCloudA    = 0;    /**< L'animation d'un nuage A */
void *animCloudB    = 0;    /**< L'animation d'un nuage B */
void *animCloudC    = 0;    /**< L'animation d'un nuage C */

float charBottom    = 0.81f;        /**< La position du personnage au sol */
float charPosX      = 0.0f;         /**< Position X du personnage */
float charPosY      = 0.0f;         /**< Position Y du personnage */
int charJump        = 0;            /**< Pour savoir si le personnage est en train de sauter (phase de montée) */
unsigned long int charTimeAnim = 0; /**< La base temporelle du personnage pour les déplacements */
unsigned long int charTimeMove = 0; /**< La base temporelle du personnage pour le saut */

/**
 * Point d'entrée de l'application.
 * @author U.Speed
 * @param int : argCount : nombre d'arguments passés au programme
 * @param char** : argValues : liste des arguments passés au programme
 */
int main(int argNumber, char *argList[])
{
    return USGE_CAPI_main("C-API - Test...", argNumber, argList, myInit, myMain, myFinish);
}

/**
 * Initialisation de l'application.
 * @author U.Speed
 */
void myInit(void)
{
    /* L'animations du nuage */
    USGE_MinCAPI_KeyFrame cloudKeyframe;

    printf("Init...\n");
    /* Chargement des surfaces */
    background  = USGE_CAPI_newSurface2D("../demoData/background.jpg", 0);
    tree        = USGE_CAPI_newSurface2D("../demoData/tree.png", 1);
    cloud       = USGE_CAPI_newSurface2D("../demoData/cloud.png", 1);
    flower      = USGE_CAPI_newSurface2D("../demoData/flower.png", 1);
    ground      = USGE_CAPI_newSurface2D("../demoData/ground.jpg", 0);
    character   = USGE_CAPI_newSurface2D("../demoData/character.png", 1);

    /* Chargement des animations */
    animCloudA  = USGE_CAPI_newAnimation();
    animCloudB  = USGE_CAPI_newAnimation();
    animCloudC  = USGE_CAPI_newAnimation();

    /* Préparation de l'animation du nuage A */
    {
        memset(&cloudKeyframe, 0, sizeof(USGE_MinCAPI_KeyFrame));
        /* Trame initiale */
        cloudKeyframe.duration = 10000;
        cloudKeyframe.xPosition = -0.3f;
        cloudKeyframe.yPosition = 0.4f;
        USGE_CAPI_addKeyFrameAnimation(animCloudA, cloudKeyframe);

        /* Trame Finale */
        cloudKeyframe.xPosition = 2.0f;
        cloudKeyframe.yPosition = 0.5f;
        USGE_CAPI_addKeyFrameAnimation(animCloudA, cloudKeyframe);
        USGE_CAPI_loopAnimation(animCloudA, 1);

        /* Lancement de l'animation */
        USGE_CAPI_playAnimation(animCloudA);
    }

    /* Préparation de l'animation du nuage B */
    {
        memset(&cloudKeyframe, 0, sizeof(USGE_MinCAPI_KeyFrame));
        /* Trame initiale */
        cloudKeyframe.duration = 20000;
        cloudKeyframe.xPosition = 2.0f;
        cloudKeyframe.yPosition = 0.7f;
        USGE_CAPI_addKeyFrameAnimation(animCloudB, cloudKeyframe);

        /* Trame Finale */
        cloudKeyframe.xPosition = -0.3f;
        cloudKeyframe.yPosition = 0.6f;
        USGE_CAPI_addKeyFrameAnimation(animCloudB, cloudKeyframe);
        USGE_CAPI_loopAnimation(animCloudB, 1);

        /* Lancement de l'animation */
        USGE_CAPI_playAnimation(animCloudB);
    }

    /* Préparation de l'animation du nuage C */
    {
        memset(&cloudKeyframe, 0, sizeof(USGE_MinCAPI_KeyFrame));
        /* Trame initiale */
        cloudKeyframe.duration = 15000;
        cloudKeyframe.xPosition = -0.3f;
        cloudKeyframe.yPosition = 0.1f;
        USGE_CAPI_addKeyFrameAnimation(animCloudC, cloudKeyframe);

        /* Trame Finale */
        cloudKeyframe.xPosition = 2.0f;
        cloudKeyframe.yPosition = 0.5f;
        USGE_CAPI_addKeyFrameAnimation(animCloudC, cloudKeyframe);
        USGE_CAPI_loopAnimation(animCloudC, 1);

        /* Lancement de l'animation */
        USGE_CAPI_playAnimation(animCloudC);
    }

    /* Plaçage du personnage */
    charPosX = 1.0f;
    charPosY = charBottom;
}

/**
 * Traitement principal.
 * @author U.Speed
 * @param elapsedTime unsigned long int : temps écoulé depuis le dernier appel
 */
void myMain(unsigned long int elapsedTime)
{
    /* Affichage des éléments à l'arrière plan */
    drawBackground();
    /* Affichage du personnage */
    drawCharacter();
    /* Affichage des éléments au premier plan */
    drawForeground();
}

/**
 * Finalisation de l'application.
 * @author U.Speed
 */
void myFinish(void)
{
    /* Suppression des éventuelles surfaces */
    USGE_CAPI_deleteSurface2D(background);
    USGE_CAPI_deleteSurface2D(tree);
    USGE_CAPI_deleteSurface2D(cloud);
    USGE_CAPI_deleteSurface2D(flower);
    USGE_CAPI_deleteSurface2D(ground);
    USGE_CAPI_deleteSurface2D(character);

    /* Suppression des éventuelles animations */
    USGE_CAPI_deleteAnimation(animCloudA);
    USGE_CAPI_deleteAnimation(animCloudB);
    USGE_CAPI_deleteAnimation(animCloudC);

    printf("Finish...\n");
}

/**
 * Affichage de l'arrière plan.
 * @author U.Speed
 */
void drawBackground(void)
{
    float position = 0.0f;

    /* Affichage du fond */
    USGE_CAPI_layerSurface2D(background, 0.0f);
    USGE_CAPI_renderSurface2D(background);

    /* Affichage du nuage B */
    USGE_CAPI_animationSurface2D(cloud, animCloudB);
    USGE_CAPI_sizeSurface2D(cloud, 0.1f, 0.1f);
    USGE_CAPI_layerSurface2D(cloud, 4.0f);
    USGE_CAPI_renderSurface2D(cloud);

    /* Affichage d'un arbre */
    USGE_CAPI_layerSurface2D(tree, 5.0f);
    USGE_CAPI_sizeSurface2D(tree, 0.5f, 0.5f);
    USGE_CAPI_positionSurface2D(tree, 0.5f, 0.42f);
    USGE_CAPI_renderSurface2D(tree);

    /* Affichage d'un mont avec une fleur */
    USGE_CAPI_uvMapSurface2D(flower, 1.0f, 0.0f, 0.0f, 1.0f);
    USGE_CAPI_layerSurface2D(flower, 6.0f);
    USGE_CAPI_sizeSurface2D(flower, 0.1f, 0.1f);
    USGE_CAPI_positionSurface2D(flower, 0.65f, 0.81f);
    USGE_CAPI_renderSurface2D(flower);

    /* Affichage d'un autre arbre */
    USGE_CAPI_layerSurface2D(tree, 7.0f);
    USGE_CAPI_sizeSurface2D(tree, 0.3f, 0.3f);
    USGE_CAPI_positionSurface2D(tree, 0.5f, 0.61f);
    USGE_CAPI_renderSurface2D(tree);

    /* Affichage d'un mont avec une fleur */
    USGE_CAPI_uvMapSurface2D(flower, 0.0f, 0.0f, 1.0f, 1.0f);
    USGE_CAPI_layerSurface2D(flower, 5.0f);
    USGE_CAPI_sizeSurface2D(flower, 0.2f, 0.2f);
    USGE_CAPI_positionSurface2D(flower, 0.1f, 0.71f);
    USGE_CAPI_renderSurface2D(flower);

    /* Affichage d'un autre arbre */
    USGE_CAPI_layerSurface2D(tree, 5.0f);
    USGE_CAPI_sizeSurface2D(tree, 0.4f, 0.4f);
    USGE_CAPI_positionSurface2D(tree, 1.35f, 0.45f);
    USGE_CAPI_renderSurface2D(tree);

    /* Affichage du sol */
    USGE_CAPI_sizeSurface2D(ground, 0.1f, 0.1f);
    USGE_CAPI_layerSurface2D(ground, 10.0f);
    position = 0.0f;
    while (position <= USGE_CAPI_screenRatio())
    {
        USGE_CAPI_positionSurface2D(ground, position, 0.9f);
        USGE_CAPI_renderSurface2D(ground);
        position += 0.1f;
    }

    /* Affichage du nuage A */
    USGE_CAPI_animationSurface2D(cloud, animCloudA);
    USGE_CAPI_sizeSurface2D(cloud, 0.3f, 0.3f);
    USGE_CAPI_layerSurface2D(cloud, 11.0f);
    USGE_CAPI_renderSurface2D(cloud);

    /* Affichage du nuage C */
    USGE_CAPI_animationSurface2D(cloud, animCloudC);
    USGE_CAPI_sizeSurface2D(cloud, 0.2f, 0.2f);
    USGE_CAPI_layerSurface2D(cloud, 12.0f);
    USGE_CAPI_renderSurface2D(cloud);
}

/**
 * Affichage du personnage.
 * @author U.Speed
 */
void drawCharacter(void)
{
    float xStart = 0.0f;    /* Coordonnées de texturage (début U) */
    float yStart = 0.0f;    /* Coordonnées de texturage (fin U) */
    float xEnd   = 0.5f;    /* Coordonnées de texturage (début V) */
    float yEnd   = 0.5f;    /* Coordonnées de texturage (fin V) */
    float tmp    = 0.0f;    /* Variable temporaire */
    int toRight  = 0;       /* En déplacement vers la droite */
    int toLeft   = 0;       /* En déplacement vers la gauche */

    /* Mise à jour de la base temporelle */
    charTimeAnim += USGE_CAPI_readChrono();
    charTimeMove += USGE_CAPI_readChrono();
    USGE_CAPI_resetChrono();

    /* Déplacement du personnage vers la droite */
    if ((USGE_CAPI_readKeyboard('D') != 0) || (USGE_CAPI_povPad(4) != 0))
    {
        toRight = 1;
    }
    else if ((USGE_CAPI_readKeyboard('Q') != 0) || (USGE_CAPI_povPad(3) != 0))
    {
        toLeft = 1;
    }
    /* On touche le sol et on veut sauter : passage en mode "saut" */
    if ((charPosY >= 0.8f) && ((USGE_CAPI_readKeyboard('Z') != 0) || (USGE_CAPI_povPad(1) != 0)))
    {
        charJump = 1;
    }

    /* Bornes de déplacement */
    if (charPosX < 0.0f)
    {
        charPosX = 0.0f;
    }
    else if (charPosX > 1.69f)
    {
        charPosX = 1.69f;
    }
    /* Intervalle de rafraîchissement de la position d'un saut ou d'un déplacement */
    if (charTimeMove > 25)
    {
        /* Déplacement */
        if (toRight != 0)
        {
            charPosX += 0.005f;
        }
        else if (toLeft != 0)
        {
            charPosX -= 0.005f;
        }
        /* Remise à zéro de la base temporelle */
        charTimeMove = 0;
        /* Borne de saut (chute si on n'est pas dans la montée) */
        if (charJump == 0)
        {
            if (charPosY < charBottom)
            {
                charPosY += 0.005f;
            }
            /* Borne du sol */
            if (charPosY > charBottom)
            {
                charPosY = charBottom;
            }
        }
        else
        {
            charPosY -= 0.005f;
            /* Haut du saut atteint */
            if (charPosY < 0.5f)
            {
                charJump = 0;
            }
        }
    }

    /* Le personnage ne bouge pas : il fait face à l'écran */
    if ((toLeft == 0) && (toRight == 0))
    {
        /* Remise à zéro de la base temporelle */
        charTimeAnim = 0;

        xStart = 0.5f;
        yStart = 0.5f;
        xEnd = 1.0f;
        yEnd = 1.0f;
    }
    else
    {
        /* On dépasse les 500 millisecondes : retour à zéro */
        if (charTimeAnim > 500)
        {
            charTimeAnim = 0;
            USGE_CAPI_resetChrono();
        }
        /* En cours de saut ? */
        if (charPosY < 0.8f)
        {
            xStart = 0.0f;
            yStart = 0.5f;
            xEnd = 0.5f;
            yEnd = 1.0f;
        }
        else
        {
            /* En déplacement */
            if (charTimeAnim < 250)
            {
                xStart = 0.0f;
                yStart = 0.0f;
                xEnd = 0.5f;
                yEnd = 0.5f;
            }
            else
            {
                xStart = 0.5f;
                yStart = 0.0f;
                xEnd = 1.0f;
                yEnd = 0.5f;
            }
        }
        /* Déplacement vers la droite : inversion de xStart et xEnd */
        if (toRight)
        {
            tmp = xStart;
            xStart = xEnd;
            xEnd = tmp;
        }
    }
    /* Affichage */
    USGE_CAPI_uvMapSurface2D(character, xStart, yStart, xEnd, yEnd);
    USGE_CAPI_layerSurface2D(character, 15.0f);
    USGE_CAPI_sizeSurface2D(character, 0.1f, 0.1f);
    USGE_CAPI_positionSurface2D(character, charPosX, charPosY);
    USGE_CAPI_renderSurface2D(character);
}

/**
 * Affichage du premier plan.
 * @author U.Speed
 */
void drawForeground(void)
{
    /* Affichage d'un arbre */
    USGE_CAPI_layerSurface2D(tree, 20.0f);
    USGE_CAPI_sizeSurface2D(tree, 0.2f, 0.2f);
    USGE_CAPI_positionSurface2D(tree, 0.7f, 0.73f);
    USGE_CAPI_renderSurface2D(tree);

    /* Affichage d'un mont avec une fleur */
    USGE_CAPI_uvMapSurface2D(flower, 0.0f, 0.0f, 1.0f, 1.0f);
    USGE_CAPI_layerSurface2D(flower, 20.0f);
    USGE_CAPI_sizeSurface2D(flower, 0.3f, 0.3f);
    USGE_CAPI_positionSurface2D(flower, 1.37f, 0.65f);
    USGE_CAPI_renderSurface2D(flower);
}
