# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
#
# Copyright (C) 2013 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Dropping Letters app autopilot tests."""

from __future__ import absolute_import

from autopilot.matchers import Eventually
from testtools.matchers import Equals, LessThan

from dropping_letters_app.tests import DroppingLettersTestCase
from time import sleep


class TestMainWindow(DroppingLettersTestCase):

    def setUp(self):
        super(TestMainWindow, self).setUp()
        self.assertThat(
            self.main_view.visible, Eventually(Equals(True)))

    def _assert_game_screen(self):
        main_score_label = self.main_view.get_main_score_label()
        self.assertTrue(main_score_label.visible)

    def test_intro_screen(self):
        helpbutton = self.main_view.get_help_button()
        # check help button popup
        self.assertTrue(helpbutton.visible)

        # open the popup
        self.pointing_device.click_object(helpbutton)

        # check and ensure help popover appears
        helpPopover = self.main_view.get_help_popover()
        properties = helpPopover.get_properties()
        self.assertTrue(properties["visible"])

        # check and ensure help popover disappears
        self.pointing_device.click_object(helpbutton)
        self.assertThat(self.main_view.get_many_popover,
                        Eventually(Equals([])))

    def test_start_new_game(self):
        toolbar = self.main_view.open_toolbar()
        toolbar.click_button('new_game')
        self._assert_game_screen()
        main_score_label = self.main_view.get_main_score_label()
        self.assertEquals(main_score_label.text, '0')

    def test_finishing_a_word(self):
        # start game and close toolbar
        toolbar = self.main_view.open_toolbar()
        toolbar.click_button('new_game')
        self._assert_game_screen()
        toolbar = self.main_view.close_toolbar()

        # check for letters falling
        # select first 2 letters; wait for 3 letters to appear
        # so first 2 are settled for clicking
        tiles = self.main_view.get_letter_tiles()
        while len(tiles) < 3:
            tiles = self.main_view.get_letter_tiles()

        # click the accumlated letters
        # check and make sure they get selected
        # add tries as a control to avoid infinite loop
        # and provide better failure feedback
        tries = 0
        self.pointing_device.click_object(tiles[0])
        tileProperties = tiles[0].get_properties()
        while (not tileProperties["selected"] and tries < 10):
            sleep(1)
            tries += 1
            self.pointing_device.click_object(tiles[0])
            tileProperties = tiles[0].get_properties()

        self.assertThat(tries, LessThan(10))

        tries = 0
        self.pointing_device.click_object(tiles[1])
        tileProperties = tiles[1].get_properties()
        while (not tileProperties["selected"] and tries < 10):
            sleep(1)
            tries += 1
            self.pointing_device.click_object(tiles[1])
            tileProperties = tiles[1].get_properties()

        self.assertThat(tries, LessThan(10))

        # check the text to make sure it's the same
        wordValue = tiles[0].containedLetter + tiles[1].containedLetter
        word = self.main_view.get_word_label()
        self.assertEquals(word.text, wordValue)

        # click to complete word
        validWord = word.isValid
        self.pointing_device.click_object(word)

        # depending on if the property isValid is true or not,
        # score should increase or stay the same after completion
        # we don't need to get fancy, since the start value is 0;
        # check for zero or non-zero score
        main_score_label = self.main_view.get_main_score_label()
        if validWord:
            self.assertNotEquals(main_score_label.text, '0')
        else:
            self.assertEquals(main_score_label.text, '0')
