<?php



namespace DoctrineExtensions\Tests\Query\Mysql;



class TrigTest extends \DoctrineExtensions\Tests\Query\MysqlTestCase

{

    public function setUp()

    {

        parent::setUp();



        $this->entity = 'DoctrineExtensions\Tests\Entities\BlogPost';

    }



    public function testSin()

    {



        $this->_assertFirstQuery('SIN');

        $this->_assertSecondQuery('SIN');



        $dql = "SELECT SIN(RADIANS(p.latitude)) FROM {$this->entity} p";

        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT SIN(RADIANS(b0_.latitude)) AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());



        $dql = "SELECT SIN(p.latitude * p.longitude) FROM {$this->entity} p";

        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT SIN(b0_.latitude * b0_.longitude) AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());



        $dql = "SELECT SIN(RADIANS(p.latitude) * RADIANS(p.longitude)) FROM {$this->entity} p";

        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT SIN(RADIANS(b0_.latitude) * RADIANS(b0_.longitude)) AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());



        if (\Doctrine\ORM\Version::compare('2.4.0') <= 0) {

            $dql = "SELECT p FROM {$this->entity} p WHERE p.longitude = SIN(RADIANS(p.latitude)) * RADIANS(p.longitude)";

        } else {

            $dql = "SELECT p FROM {$this->entity} p WHERE p.longitude = (SIN(RADIANS(p.latitude)) * RADIANS(p.longitude))";

        }



        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT b0_.id AS id_0, b0_.created AS created_1, b0_.longitude AS longitude_2, b0_.latitude AS latitude_3 FROM BlogPost b0_ WHERE b0_.longitude = SIN(RADIANS(b0_.latitude)) * RADIANS(b0_.longitude)";

        $this->assertEquals($sql, $q->getSql());



        $dql = "SELECT p FROM {$this->entity} p WHERE SIN(RADIANS(p.latitude)) * SIN(RADIANS(p.longitude)) = 1";

        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT b0_.id AS id_0, b0_.created AS created_1, b0_.longitude AS longitude_2, b0_.latitude AS latitude_3 FROM BlogPost b0_ WHERE SIN(RADIANS(b0_.latitude)) * SIN(RADIANS(b0_.longitude)) = 1";

        $this->assertEquals($sql, $q->getSql());



        if (\Doctrine\ORM\Version::compare('2.4.0') <= 0) {

            $dql = "SELECT SIN(RADIANS(p.latitude)) * SIN(RADIANS(p.longitude)) FROM {$this->entity} p ";

        } else {

            $dql = "SELECT (SIN(RADIANS(p.latitude)) * SIN(RADIANS(p.longitude))) FROM {$this->entity} p ";

        }



        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT SIN(RADIANS(b0_.latitude)) * SIN(RADIANS(b0_.longitude)) AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());

    }



    public function testAsin()

    {

        $this->_assertFirstQuery('ASIN');

        $this->_assertSecondQuery('ASIN');

    }



    public function testAcos()

    {

        $this->_assertFirstQuery('ACOS');

        $this->_assertSecondQuery('ACOS');



        if (\Doctrine\ORM\Version::compare('2.4.0') <= 0) {

            $dql = "SELECT ACOS(SIN(RADIANS(p.latitude)) + SIN(RADIANS(p.longitude))) * 1 FROM {$this->entity} p";

        } else {

            $dql = "SELECT (ACOS(SIN(RADIANS(p.latitude)) + SIN(RADIANS(p.longitude))) * 1) FROM {$this->entity} p";

        }



        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT ACOS(SIN(RADIANS(b0_.latitude)) + SIN(RADIANS(b0_.longitude))) * 1 AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());

    }



    public function testCos()

    {

        $this->_assertFirstQuery('COS');

        $this->_assertSecondQuery('COS');

    }



    public function testCot()

    {

        $this->_assertFirstQuery('COT');

        $this->_assertSecondQuery('COT');

    }



    public function testDegrees()

    {

        $this->_assertFirstQuery('DEGREES');

        $this->_assertSecondQuery('DEGREES');

    }



    public function testRadians()

    {

        $this->_assertFirstQuery('RADIANS');

        $this->_assertSecondQuery('RADIANS');

    }



    public function testTan()

    {

        $this->_assertFirstQuery('TAN');

        $this->_assertSecondQuery('TAN');

    }



    public function testAtan()

    {

        // test with 1 argument

        $this->_assertFirstQuery('ATAN');

        $this->_assertSecondQuery('ATAN');



        // test with 2 arguments

        $dql = "SELECT ATAN(p.latitude, p.longitude) FROM {$this->entity} p ";

        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT ATAN(b0_.latitude, b0_.longitude) AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());

    }



    public function testAtan2()

    {

        $dql = "SELECT ATAN2(p.latitude, p.longitude) FROM {$this->entity} p";

        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT ATAN2(b0_.latitude, b0_.longitude) AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());

    }



    public function testCosineLaw()

    {

        $lat = 0.0;

        $lng = 0.0;

        $radiusOfEarth = 6371;



        $cosineLaw = 'ACOS(SIN(' . deg2rad($lat) . ') * SIN(RADIANS(p.latitude)) '

                . '+ COS(' . deg2rad($lat) . ') * COS(RADIANS(p.latitude)) '

                . '* COS(RADIANS(p.longitude) - ' . deg2rad($lng) . ')'

                . ') * ' . $radiusOfEarth;



        if (\Doctrine\ORM\Version::compare('2.4.0') <= 0) {

            $dql = "SELECT " . $cosineLaw . " FROM {$this->entity} p";

        } else {

            $dql = "SELECT (" . $cosineLaw . ") FROM {$this->entity} p";

        }



        $q = $this->entityManager->createQuery($dql);



        $sql = "SELECT ACOS(SIN(0) * SIN(RADIANS(b0_.latitude)) + COS(0) * COS(RADIANS(b0_.latitude)) * COS(RADIANS(b0_.longitude) - 0)) * 6371 AS sclr_0 FROM BlogPost b0_";

        $this->assertEquals($sql, $q->getSql());

    }



    protected function _assertFirstQuery($func)

    {

        $q = $this->_getFirstDqlQuery($func);

        $sql = $this->_getFirstSqlQuery($func);

        $this->assertEquals($sql, $q->getSql());

    }



    protected function _assertSecondQuery($func)

    {

        $q = $this->_getSecondDqlQuery($func);

        $sql = $this->_getSecondSqlQuery($func);

        $this->assertEquals($sql, $q->getSql());

    }



    protected function _getFirstDqlQuery($func)

    {

        $dql = "SELECT p FROM {$this->entity} p WHERE " . $func . "(p.latitude) = 1";



        return $this->entityManager->createQuery($dql);

    }



    protected function _getFirstSqlQuery($func)

    {

        return "SELECT b0_.id AS id_0, b0_.created AS created_1, "

        . "b0_.longitude AS longitude_2, b0_.latitude AS latitude_3 "

        . "FROM BlogPost b0_ WHERE " . $func . "(b0_.latitude) = 1";

    }



    protected function _getSecondDqlQuery($func)

    {

        $dql = "SELECT " . $func . "(p.latitude) FROM {$this->entity} p";



        return $this->entityManager->createQuery($dql);

    }



    protected function _getSecondSqlQuery($func)

    {

        return "SELECT " . $func . "(b0_.latitude) AS sclr_0 FROM BlogPost b0_";

    }

}

