# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
# Copyright 2012-2014 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.

from __future__ import print_function
import logging
from PyQt5 import QtCore, QtWidgets
import six
import sys

from windowmocker.plugins.base import ApplicationTypePluginBase

logger = logging.getLogger(__name__)

class QtPlugin(ApplicationTypePluginBase):

    Name = "Qt5"

    def create_application(self):
        args = sys.argv[:1]
        if "-testability" in sys.argv:
            args.append("-testability")
        self.app = QtWidgets.QApplication(args)

    def create_window(self, window_spec):
        win = QtWidgets.QMainWindow()
        win.setWindowTitle(window_spec["Title"])

        if 'Menu' in window_spec:
            menu_bar = win.menuBar()
            self._create_menus(menu_bar, window_spec['Menu'])

        control_spec = window_spec.get('Contents', None)
        if control_spec is not None:
            controls = self._create_controls(control_spec)
            win.setCentralWidget(controls)

        if window_spec['Maximized']:
            win.showMaximized()
        if window_spec['Minimized']:
            win.showMinimized()

        if not window_spec['Maximized'] and not window_spec['Minimized']:
            win.showNormal()

        # In some cases, it's also needed to have the application start
        # normally but minimize itself right after starting
        if window_spec['MinimizeImmediatelyAfterShow']:
            win.setWindowState(QtCore.Qt.WindowMinimized)

        if not getattr(self, 'windows', None):
            self.windows = []
        self.windows.append(win)

    def _create_menus(self, parent, menu_spec):
        for item in menu_spec:
            if type(item) is dict:
                title = item.get('Title', 'Default Title')
                menu = parent.addMenu(title)
                if 'Menu' in item:
                    self._create_menus(menu, item['Menu'])
            elif isinstance(item, six.string_types):
                parent.addAction(item)
            else:
                logger.error("Invalid menu item - is not a dict or string: %r", item)

    def _create_controls(self, control_spec):
        if control_spec == 'TextEdit':
            return QtWidgets.QTextEdit()
        elif control_spec == 'MouseTest':
            return MouseTestWidget()



    def run(self):
        self.app.exec_()


class MouseTestWidget(QtWidgets.QWidget):

    def __init__(self):
        super(MouseTestWidget, self).__init__()
        self.setAttribute(QtCore.Qt.WA_AcceptTouchEvents)
        self.button_control = QtWidgets.QLabel(self)
        self.button_control.setAttribute(QtCore.Qt.WA_AcceptTouchEvents)
        self.button_control.setObjectName("button_status")
        self.position_control = QtWidgets.QLabel(self)
        self.position_control.setAttribute(QtCore.Qt.WA_AcceptTouchEvents)
        self.position_control.setObjectName("position_status")
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.button_control)
        layout.addWidget(self.position_control)

        self.setMouseTracking(True)
        self.button_control.setMouseTracking(True)
        self.position_control.setMouseTracking(True)

    def event(self, event):
        if event.type() == QtCore.QEvent.TouchBegin:
            self.touchBegin(event)
        elif event.type() == QtCore.QEvent.TouchUpdate:
            self.touchUpdate(event)
        elif event.type() == QtCore.QEvent.TouchEnd:
            self.touchEnd(event)
        else:
            return super(MouseTestWidget, self).event(event)
        return True

    def touchBegin(self, event):
        self.button_control.setText("Touch Press")

    def touchUpdate(self, event):
        pass

    def touchEnd(self, event):
        self.button_control.setText("Touch Release")

    def mousePressEvent(self, mouseEvent):
        btn_name = self._get_button_string(mouseEvent.button())
        self.button_control.setText("Press " + btn_name)

    def mouseReleaseEvent(self, mouseEvent):
        btn_name = self._get_button_string(mouseEvent.button())
        self.button_control.setText("Release " + btn_name)

    def mouseMoveEvent(self, mouseEvent):
        pos = mouseEvent.globalPos()
        self.position_control.setText("Position: ({}, {})".format(pos.x(), pos.y()))

    def wheelEvent(self, wheelEvent):
        direction = "down" if wheelEvent.delta() < 0 else "up"
        self.button_control.setText("Wheel {}".format(direction))

    def _get_button_string(self, btn):
        if btn == QtCore.Qt.LeftButton:
            return "Left"
        elif btn == QtCore.Qt.RightButton:
            return "Right"
        elif btn == QtCore.Qt.MiddleButton:
            return "Middle"
        else:
            return "Other"
