/***** THIS FILE CANNOT BE RELICENSED UNDER THE MPL YET *****/

/*
 * QML Material - An application framework implementing Material Design.
 * Copyright (C) 2015 Michael Spencer <sonrisesoftware@gmail.com>
 *
 * 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, either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * 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/>.
 */
import QtQuick 2.4
import QtQuick.Layouts 1.1

import Material 0.3
import Material.ListItems 0.1

/*!
   \qmltype MenuField
   \inqmlmodule Material

   \brief A input field similar to a text field but that opens a dropdown menu.
 */
Item {
    id: field

    implicitHeight: hasHelperText ? helperTextLabel.y + helperTextLabel.height + 4 * Units.dp
                                  : underline.y + 8 * Units.dp
    implicitWidth: spinBoxContents.implicitWidth

    activeFocusOnTab: true

    property color accentColor: Theme.accentColor
    property color errorColor: "#F44336"

    property alias model: listView.model

    property string textRole
    property string idRole

    readonly property string selectedText: (listView.currentItem) ? listView.currentItem.text : ""

    property alias selectedIndex: listView.currentIndex
    property string selectedID: ""
    property int maxVisibleItems: 4

    property alias placeholderText: fieldPlaceholder.text
    property alias helperText: helperTextLabel.text

    property bool floatingLabel: false
    property bool hasError: false
    property bool hasHelperText: helperText.length > 0

    readonly property rect inputRect: Qt.rect(spinBox.x, spinBox.y, spinBox.width, spinBox.height)
    property bool isInitialized:false

    signal itemSelected(int index)

    function setIndex(startSelectedIndex) {
        isInitialized = true;
        selectedIndex = -1;
        selectedIndex = startSelectedIndex;
    }

    Ink {
        anchors.fill: parent
        onClicked: {
            if(listView.currentItem) {
                listView.positionViewAtIndex(listView.currentIndex, ListView.Center)
                var offset = listView.currentItem.itemLabel.mapToItem(menu, 0, 0)
                menu.open(label, 0, -offset.y)
            }
        }
    }

    Item {
        id: spinBox

        height: 24 * Units.dp
        width: parent.width

        y: {
            if(!floatingLabel)
                return 16 * Units.dp
            if(floatingLabel && !hasHelperText)
                return 40 * Units.dp
            return 28 * Units.dp
        }

        RowLayout {
            id: spinBoxContents

            height: parent.height
            width: parent.width + 5 * Units.dp

            Label {
                id: label

                Layout.fillWidth: true
                Layout.alignment: Qt.AlignVCenter

                text: (listView.currentItem) ? listView.currentItem.text : ""
                style: "subheading"
                elide: Text.ElideRight
            }

            Icon {
                id: dropDownIcon

                Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
                Layout.preferredWidth: 24 * Units.dp
                Layout.preferredHeight: 24 * Units.dp

                name: "navigation/arrow_drop_down"
                size: 24 * Units.dp
            }
        }

        Dropdown {
            id: menu

            anchor: Item.TopLeft

            width: spinBox.width

            //If there are more than max items, show an extra half item so
            // it's clear the user can scroll
            height: Math.min(maxVisibleItems*48 * Units.dp + 24 * Units.dp, listView.contentHeight)

            ListView {
                id: listView

                width: menu.width
                height: count > 0 ? menu.height : 0

                interactive: true

                delegate: Standard {
                    id: delegateItem
                    property bool isCurrentItem: ListView.isCurrentItem
                    property string itemId:{
                        if(idRole) {
                            if(model.modelData && model.modelData[idRole]){
                                selectedID = model.modelData[idRole];
                            }else{
                                if( model[idRole]){
                                    model[idRole];
                                }else{
                                    '';
                                }

                            }
                        }else{
                            '';
                        }
                    }

                    text: {
                        if(textRole){
                            if(model.modelData && model.modelData[textRole]){
                                model.modelData[textRole];
                            }else{
                                if(model[textRole]){
                                    model[textRole];
                                }else{
                                    '';
                                }
                            }
                        }else{
                            modelData;
                        }
                    }


                    onIsCurrentItemChanged:{
                        if(isInitialized){
                            if(isCurrentItem){

                                selectedID = itemId;
                            }
                            itemSelected(index);
                        }
                    }


                    onClicked: {
                        selectedID = itemId;
                        listView.currentIndex = index;
                        itemSelected(index);
                        menu.close();
                    }
                }
            }

            Scrollbar {
                flickableItem: listView
            }
        }
    }

    Label {
        id: fieldPlaceholder

        text: field.placeholderText
        visible: floatingLabel

        font.pixelSize: 12 * Units.dp

        anchors.bottom: spinBox.top
        anchors.bottomMargin: 8 * Units.dp

        color: Theme.light.hintColor
    }

    Rectangle {
        id: underline

        color: field.hasError ? field.errorColor : field.activeFocus ? field.accentColor : Theme.light.hintColor

        height: field.activeFocus ? 2 * Units.dp : 1 * Units.dp

        anchors {
            left: parent.left
            right: parent.right
            top: spinBox.bottom
            topMargin: 8 * Units.dp
        }

        Behavior on height {
            NumberAnimation { duration: 200 }
        }

        Behavior on color {
            ColorAnimation { duration: 200 }
        }
    }

    Label {
        id: helperTextLabel

        anchors {
            left: parent.left
            right: parent.right
            top: underline.top
            topMargin: 4 * Units.dp
        }

        visible: hasHelperText
        font.pixelSize: 12 * Units.dp
        color: field.hasError ? field.errorColor : Qt.darker(Theme.light.hintColor)

        Behavior on color {
            ColorAnimation { duration: 200 }
        }
    }
}
