"""Base class for game application."""

import os
import time

from xoinvader.common import Settings
# TODO: Think about protocol between Application and SettingsManager

class Application(object):
    def __init__(self, startup_args=None):
        self._state = None
        self._states = {}
        self._mspf = None # ms per frame
        self._running = False

        if startup_args:
            self._update_settings(startup_args)

    def _update_settings(self, args):
        for arg, val in args.items():
            if arg in Settings.system:
                Settings.system[arg] = val
            else:
                raise KeyError("No such argument: '%s'." % arg)

    @property
    def running(self):
        return self._running

    @property
    def state(self):
        if self._state:
            return self._state.__class__.__name__
        else:
            raise AttributeError("There is no available state.")

    @state.setter
    def state(self, name):
        if name in self._states:
            self._state = self._states[name]
        else:
            raise KeyError("No such state: '{0}'.".format(name))

    def register_state(self, state):
        """Add new state and initiate it with owner."""
        name = state.__name__
        self._states[name] = state(self)
        if len(self._states) == 1:
            self._state = self._states[name]

    def stop(self):
        self._running = False

    def loop(self):
        if self._state:
            self._running = True
        else:
            raise AttributeError("There is no avalable state.")

        while self._running:
            start_time = time.perf_counter()

            self._state.events()
            self._state.update()
            self._state.render()

            finish_time = time.perf_counter()
            delta = finish_time - start_time
            if delta <= self._mspf:
                time.sleep((self._mspf - delta) / 1000.0)
            else:
                pass # Log FPS drawdowns.

        return os.EX_OK

@@ -191,16 +191,250 @@
 bject):%0A
+    %22%22%22Base class for game applications.%0A%0A    :param startup_args: arguments for passing to game settings%0A    :type startup_args: dict%0A%0A    :return: Application instance%0A    :rtype: :class:%60xoinvader.application.Application%60%0A    %22%22%22%0A%0A
     def 
@@ -705,16 +705,143 @@
  args):%0A
+        %22%22%22Update system settings from startup arguments.%0A%0A        :param args: arguments%0A        :type args: dict%0A        %22%22%22%0A
         
@@ -1084,64 +1084,309 @@
     
-return self._running%0A%0A    @property%0A    def state(self):
+%22%22%22Is game running or not.%0A%0A        :getter: get application status%0A        :type: boolean%0A        %22%22%22%0A        return self._running%0A%0A    @property%0A    def state(self):%0A        %22%22%22Current state.%0A%0A        :getter: Return current state%0A        :setter: Set current state%0A        :type: string%0A        %22%22%22
 %0A   
@@ -1828,16 +1828,124 @@
 h owner.
+%0A%0A        :param state: state class to register%0A        :type state: :class:%60xoinvader.state.State%60%0A        
 %22%22%22%0A    
@@ -2104,32 +2104,64 @@
 def stop(self):%0A
+        %22%22%22Stop application.%22%22%22%0A
         self._ru
@@ -2187,32 +2187,148 @@
 def loop(self):%0A
+        %22%22%22Start main application loop.%0A%0A        :return: execution status code%0A        :trype: integer%0A        %22%22%22%0A
         if self.

add docstrings.