'''
Compass example
===============

This example is a demonstration of Hardware class usage.
But it has severals drawbacks, like using only the magnetic sensor, and
extrapolating values to get the orientation. The compass is absolutely not
accurate.

The right way would be to get the accelerometer + magnetic, and computer
everything according to the phone orientation. This is not the purpose of this
example right now.

You can compile it with::

    ./build.py --package org.test.compass --name compass \
        --private ~/code/kivy/examples/android/compass \
        --window --version 1.0 debug installd
'''


import kivy
kivy.require('1.7.0')

from jnius import autoclass
from math import floor
from kivy.app import App
from kivy.properties import NumericProperty
from kivy.clock import Clock
from kivy.vector import Vector
from kivy.animation import Animation

Hardware = autoclass('org.renpy.android.Hardware')


class CompassApp(App):

    needle_angle = NumericProperty(0)

    def build(self):
        self._anim = None
        Hardware.magneticFieldSensorEnable(True)
        Clock.schedule_interval(self.update_compass, 1 / 10.)

    def update_compass(self, *args):
        # read the magnetic sensor from the Hardware class
        (x, y, z) = Hardware.magneticFieldSensorReading()

        # calculate the angle
        needle_angle = Vector(x, y).angle((0, 1)) + 90.

        # fix animation transition around the unit circle
        if (self.needle_angle % 360) - needle_angle > 180:
            needle_angle += 360
        elif (self.needle_angle % 360) - needle_angle < -180:
            needle_angle -= 360
        # add the number of revolutions to the result
        needle_angle += 360 * floor(self.needle_angle / 360.)

        # animate the needle
        if self._anim:
            self._anim.stop(self)
        self._anim = Animation(needle_angle=needle_angle, d=.2, t='out_quad')
        self._anim.start(self)

    def on_pause(self):
        # when you are going on pause, don't forget to stop the sensor
        Hardware.magneticFieldSensorEnable(False)
        return True

    def on_resume(self):
        # reactivate the sensor when you are back to the app
        Hardware.magneticFieldSensorEnable(True)


if __name__ == '__main__':
    CompassApp().run()
