/*************************************************************************
     * FUNCION: public void GetDigitalMotion( out HorMotion horMotion,       *
     *                                        out VerMotion verMotion,       *
     *                                        out TurnMotion turnMotion)     *
     * DESCRIPCION: Función encargada de obtener el movimiento de traslación *
     *   y rotación digital que el objeto está realizando actualmente.       *
     * ARGUMENTOS:                                                           *
     *   ENTRADA: Ninguno.                                                   *
     *   SALIDA: HorMotion horMotion: Movimiento digital en el eje horzontal *
     *           VerMotion verMotion: Movimiento digital en el eje vertical  *
     *           TurnMotion turnMotion: Movimiento digital de rotación.      *
     * RETORNO: Ninguno.                                                     *
     *************************************************************************/
    public void GetDigitalMotion( out HorMotion horMotion, out VerMotion verMotion, 
		                          out TurnMotion turnMotion)
    {
        horMotion = this.horMotion;
        verMotion = this.verMotion;
        turnMotion = this.turnMotion;
    }
    /*************************************************************************
     * FUNCION: void ConfigManualDigitalMotion()                             *
     * DESCRIPCION: Función encargada de obtener el nuevo tipo de movimiento *
     *   digital, introducido por el usuario, que va a realizar el objeto en *
     *   la siguiente acción.                                                *
     * ARGUMENTOS:                                                           *
     *   ENTRADA: Ninguno.                                                   *
     *   SALIDA: Ninguno.                                                    *
     * RETORNO: Ninguno (void)                                               *
     *************************************************************************/
    void ConfigManualDigitalMotion()
    {
        // Se guarda la entrada digital horizontal del teclado pulsado por el usuario.
        if (Input.GetKey( KeyCode.LeftArrow))
        {
            if (!Input.GetKey( KeyCode.RightArrow) || (horMotion != HorMotion.right))
                horMotion = HorMotion.left;
        }
        else if (Input.GetKey( KeyCode.RightArrow))
            horMotion = HorMotion.right;
        else
            horMotion = HorMotion.idle;

        // Se guarda la entrada digital vertical del teclado pulsado por el usuario.
        if (Input.GetKey( KeyCode.UpArrow))
        {
            if (!Input.GetKey( KeyCode.DownArrow) || (verMotion != VerMotion.back))
                verMotion = VerMotion.forward;
        }
        else if (Input.GetKey( KeyCode.DownArrow))
            verMotion = VerMotion.back;
        else
            verMotion = VerMotion.idle;

        // Se guarda la entrada digital de giro del teclado pulsado por el usuario.
        if (Input.GetKey( KeyCode.Z))
        {
            if (!Input.GetKey( KeyCode.X) || (turnMotion != TurnMotion.right))
                turnMotion = TurnMotion.left;
        }
        else if (Input.GetKey( KeyCode.X))
            turnMotion = TurnMotion.right;
        else
            turnMotion = TurnMotion.idle;
    }
    /*************************************************************************
     * FUNCION: void ConfigAutoDigitalMotion()                               *
     * DESCRIPCION: Función encargada de generar el nuevo tipo de movimiento *
     *   digital, calculado por la máquina, que va a realizar el objeto en   *
     *   la siguiente acción, junto con el tiempo que tardará en realizar    *
     *   dicho movimiento.                                                   *
     * ARGUMENTOS:                                                           *
     *   ENTRADA: Ninguno.                                                   *
     *   SALIDA: Ninguno.                                                    *
     * RETORNO: Ninguno (void)                                               *
     *************************************************************************/
    void ConfigAutoDigitalMotion()
    {
        // Se obtiene el tiempo en segundos que va a durar el nuevo movimiento a realizar
        iCurrentMotionTime = (bRandomTime) ? Random.Range( 1, iMotionTime+1) : iMotionTime;

        fStartTime = Time.timeSinceLevelLoad;  // Momento del tiempo en que se inicia el nuevo movimiento.

        // Se obtiene la nueva entrada de teclado digital como si la máquina pulsase las teclas de movimiento
        horMotion = (HorMotion) Random.Range( (int)HorMotion.left, (int)HorMotion.right + 1);
        verMotion = (VerMotion) Random.Range( (int)VerMotion.back, (int)VerMotion.forward + 1);
        turnMotion = (TurnMotion) Random.Range( (int)TurnMotion.left, (int)TurnMotion.right + 1);
    }
    /*************************************************************************
     * FUNCION: void ConfigAutoDigitalMotion()                               *
     * DESCRIPCION: Función encargada de generar el nuevo tipo de movimiento *
     *   digital, calculado por la máquina, que va a realizar el objeto en   *
     *   la siguiente acción. El tipo de movimiento depende del estado de la *
     *   acción actual del bot: normal, kamikaze o death.                    *
     * ARGUMENTOS:                                                           *
     *   ENTRADA: Ninguno.                                                   *
     *   SALIDA: Ninguno.                                                    *
     * RETORNO: Ninguno (void)                                               *
     *************************************************************************/
    void ConfigAutoDigitalMotion()
    {
        switch (statusBot.action)
        {
        case StatusBot.Action.normal:

            // Si el movimiento ha superado el tiempo de duración o se le fuerza a cambiar de movimiento
            // se configura un nuevo movimiento digital automático
            if (((Time.timeSinceLevelLoad - fStartTime) > fCurrentMotionTime) || bNewMotion)
            {
                bNewMotion = false;
                // Se obtiene el tiempo en segundos que va a durar el nuevo movimiento a realizar
                fCurrentMotionTime = (bRandomTime) ? Random.Range( 1, fMaxMotionTime + 1) : fMaxMotionTime;
                fStartTime = Time.timeSinceLevelLoad;  // Momento del tiempo en que se inicia el nuevo movimiento.

                // Se obtiene la nueva entrada de teclado digital como si la máquina pulsase las teclas de movimiento
                horMotion = (HorMotion) Random.Range( (int)HorMotion.left, (int)HorMotion.right + 1);
                verMotion = (VerMotion) Random.Range( (int)VerMotion.back, (int)VerMotion.forward + 1);
                turnMotion = (TurnMotion) Random.Range( (int)TurnMotion.left, (int)TurnMotion.right + 1);
            }

            break;

        case StatusBot.Action.kamikaze:
            // Vector dirección desde la posicion del bot a la posición del objeto usuario que se quiere kamikazear
            Vector3 vDirKamikaze = statusBot.objKamikaze.transform.position - thisTransform.position;

            // Se obtiene el movimiento vertical digital
            verMotion = (Vector3.Dot( thisTransform.forward, vDirKamikaze) >= 0) ? VerMotion.forward : VerMotion.back;

            // Movimiento digital horizontal y digital de giro
            float fDotHor;
            if ((fDotHor = Vector3.Dot( thisTransform.right, vDirKamikaze)) > 0)
            {
                turnMotion = (verMotion == VerMotion.forward) ? TurnMotion.right : TurnMotion.left;
                horMotion = HorMotion.right;
            }
            else if (fDotHor < 0)
            {
                turnMotion = (verMotion == VerMotion.forward) ? TurnMotion.left : TurnMotion.right;
                horMotion = HorMotion.left;
            }
            else
            {
                horMotion = HorMotion.idle;
                turnMotion = TurnMotion.idle;
            }

            break;

        case StatusBot.Action.death:
            horMotion = HorMotion.idle;
            verMotion = VerMotion.idle;
            turnMotion = TurnMotion.idle;
            break;
        default:
            break;
        }
    }