/* Copyright (C) 2014-2016 Dan Chapman <dpniel@ubuntu.com>

   This file is part of Dekko email client for Ubuntu Devices/

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License or (at your option) 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.4
import Ubuntu.Components 1.3
import Ubuntu.Components.ListItems 1.1
import Ubuntu.Components.Popups 1.0
import Dekko.Composition 0.2
import Dekko.Theme 0.2
import Dekko.Utils 0.2
import "../../Utils/Utils.js" as Utils

ListItem {
    id: recipientField

    property int recipientKind: Recipient.TO
    property alias model: filterModel.source
    // default is RecipientsFilterModel.FILTER_TO
    property alias filterRole: filterModel.filterRole
    property bool showCcBcc: false

    signal addRecipient(int type, string address)

    readonly property bool isCollapsed: state === "collapsed"

    function getInputFocus() {
        focusInputTimer.start()
    }

    function checkForUncommitedRecipients() {
        if (input.text) {
            if (internal.validateAddress(input.text)) {
                console.log("RecipientInput >> Uncommitted text is a valid address... apending to model.")
                addRecipient(recipientKind, internal.formatAddresses(input.text));
            } else {
                // We don't raise a dialog here as this is called during the send process which,
                // isn't interuptable at this point in time. Let's just wait for the "No destination" error to fail this
                console.log("RecipientInput >> Uncommitted text is not a valid address... Ignoring & clearing input.")
                input.text = ""
            }
        }
    }

    state: "collapsed"
    states: [
        State {
            name: "collapsed"
            when: !input.activeFocus
            PropertyChanges {
                target: recipientField
                height: units.gu(5)
            }
            PropertyChanges {
                target: input
                anchors.topMargin: units.gu(0.5)
            }
        },
        State {
            name: "focused"
            when: input.activeFocus
            PropertyChanges {
                target: recipientField
                height: flow.height > units.gu(6) ?
                            flow.height + contactPicker.height + units.gu(1) :
                            units.gu(6) + contactPicker.height
            }
            PropertyChanges {
                target: input
                anchors.topMargin: units.gu(0.5)
            }
        }
    ]

    MouseArea {
        anchors.fill: parent
        visible: isCollapsed
        z: 10
        onClicked: {
            mouse.accepted = true
            input.forceActiveFocus();
        }
    }

    Behavior on height {
        UbuntuNumberAnimation{}
    }

    // this displays the "To:, Cc:, Bcc:" strings
    TypeLabel {
        id: typeLabel
        height: units.gu(5)
        text: getRecipientKindName(recipientKind) + " : "
    }

    RecipientsFilterModel {
        id: filterModel
        filterRole: RecipientsFilterModel.FILTER_TO
    }

    Flow {
        id: flow

        anchors {
            left: typeLabel.right
            top: parent.top
            topMargin: units.gu(1)
            leftMargin: units.gu(1)
            right: ccBccButton.left
            rightMargin: ccBccButton.visible && !showCcBcc ? units.gu(0.5) : units.gu(2)
        }
        spacing: units.gu(1)
        Repeater {
            id: repeater
            model: filterModel
            delegate: RecipientDelegate {
                text: model.name ? model.name : model.email
                emailAddress: model.email
                onRemove: msgComposer.recipients.model.remove(filterModel.getDeproxifiedIndex(model.qtObject))
            }
        }
        Item {
            height: units.gu(4)
            width: parent.width
            RecipientInput {
                id: input
                anchors {
                    top: parent.top
                    topMargin: units.gu(0.5)
                    left: parent.left
                    right: parent.right
                }
                placeholderText: qsTr("Enter recipient address")
                Keys.onReturnPressed: addRecipient(recipientKind, internal.formatAddresses(input.text))
                onCompletionTokenSeen: addRecipient(recipientKind, internal.formatAddresses(input.text));
            }
        }
    }

    AbstractButton {
        id: ccBccButton
        visible: recipientKind === Recipient.TO && !showCcBcc
        z: 11
        anchors {
            right: parent.right
            top: parent.top
            rightMargin: units.gu(2)
        }
        height: units.gu(5)
        width: visible ? ccLabel.width : 0
        Label {
            id: ccLabel
            anchors {
                right: parent.right
                verticalCenter: parent.verticalCenter
            }
            text: qsTr("Cc/Bcc")
            fontSize: "small"
            font.weight: Style.common.fontWeight
        }
        onClicked: showCcBcc = !showCcBcc
    }


    TypeAheadContactsPicker {
        id: contactPicker
        anchors {
            top: flow.bottom
        }
        width: parent.width
        text: input.text
        onAddRecipient: {
            recipientField.addRecipient(recipientKind, address)
            input.text = ""
            input.forceActiveFocus()
        }

        Rectangle {
            id: div
            width: parent.width
            height: units.dp(1)
            color: Qt.rgba(0,0,0,0.075);
            anchors.top: parent.top
        }
    }


    QtObject {
        id: internal
        property var _errorPopover: undefined
        property int hiddenCount: 0
        onHiddenCountChanged: console.log("Hidden count: ", hiddenCount)
        function formatAddresses(text) {
            if (text) {
                var email = text.trim()
                if (validateAddress(email)) {
                    input.text = ""
                    input.placeholderText = qsTr("Add another recipient");
                    return email
                } else {
                    input.focus = false;
                    if (!_errorPopover) {
                        _errorPopover = PopupUtils.open(Qt.resolvedUrl("../../Dialogs/InfoDialog.qml"),
                                                        dekko,
                                                        {
                                                            title: qsTr("Ooops!"),
                                                            text: qsTr("'%1' doesn't seem to be a valid email address").arg(input.text)
                                                        }
                                                        );
                        _errorPopover.close.connect(function() {
                            _errorPopover = undefined;
                            focusInputTimer.start();
                        });
                    }
                }
            }
        }
        function validateAddress(email) {
            return EmailValidator.validate(email)
        }
    }

    Timer {
        id: focusInputTimer
        interval: 200
        repeat: false
        onTriggered: {
            // We've been called after an invalid recipient address dialog
            // We first need to regain focus and the send an Qt::End_Key event
            // To easily position the cursor at the end of the current text
            input.forceActiveFocus()
            TabEventSignaler.sendEndEvent()
        }
    }
}
