/*
 * EditSomeXML is a graphical XML editor
 * 
 * Copyright (C) 2014  David Jackson
 * 
 * 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 3 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 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/>.
 * 
 */

package editor.views;

import editor.controllers.AttributesPanelController;
import editor.views.viewlisteners.AttributeDocumentListener;
import editor.views.viewlisteners.DeleteAttributeListener;
import xml.Element;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

/**
 * The AttributesPanelView is used to show all of the attributes of an XML
 * element in an editable form.
 * @see xml.Element
 */
public class AttributesPanelView extends JPanel {
    private final String DEFAULT_ATTRIBUTE_BASE_NAME = "attribute";
    private final String DEFAULT_ATTRIBUTE_VALUE = "";

    private Element elem;
    private JPanel attributesPanel;
    private ArrayList<JTextField> attributeNameFields;
    private ArrayList<JTextField> attributeValueFields;
    private ArrayList<JButton> deleteButtons;
    private GridLayout layout;
    private final int NUM_COLS = 3;
    private final int MIN_NUM_ROWS = 1;
    private ArrayList<AttributeDocumentListener> listeners;
    private AttributesPanelController controller;
    private ElementEditorView editorView;

    /**
     * Initialize the AttributesPanelView with no data
     * @param element The element whose attributes this view represents
     * @param editorView The editor with which these attributes are associated
     */
    public AttributesPanelView(Element element, ElementEditorView editorView) {
        elem = element;
        this.editorView = editorView;

        listeners = new ArrayList<AttributeDocumentListener>();

        attributeNameFields = new ArrayList<JTextField>();
        attributeValueFields = new ArrayList<JTextField>();
        deleteButtons = new ArrayList<JButton>();

        controller = new AttributesPanelController(this);

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        add(new JLabel("Attributes"));

        attributesPanel = new JPanel();
        layout = new GridLayout();
        layout.setColumns(NUM_COLS);
        attributesPanel.setLayout(layout);
        add(attributesPanel);

        JButton newAttributeButton = new JButton("Add Attribute");
        newAttributeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                addAttribute();
            }
        });
        add(newAttributeButton);
    }

    /**
     * Add more space for another attribute to be added. This adds a field for
     * the attribute's name and another for its value.
     *
     * @param name The attribute's name
     * @param value The attribute's value
     */
    public void addAttribute(String name, String value) {
        if (elem == null) {
            return; // Bail out if no element is set
        }

        editorView.stopObserving();

        // Notify controller to add attribute to element model
        controller.attachAttributeToElement(name, value);

        // Add the attribute to the UI
        if (getNumberOfAttributeRows() >  0) {
            layout.setRows(layout.getRows() + 1);
        }

        JTextField nameField = new JTextField(name, 10);
        attributesPanel.add(nameField);
        attributeNameFields.add(nameField);

        JTextField valueField = new JTextField(value, 10);
        attributesPanel.add(valueField);
        attributeValueFields.add(valueField);

        int attIndex = layout.getRows() - 1;

        AttributeDocumentListener listener;
        listener = new AttributeDocumentListener(elem, attIndex, nameField,
                valueField, editorView);
        nameField.getDocument().addDocumentListener(listener);
        valueField.getDocument().addDocumentListener(listener);
        listeners.add(listener);

        JButton deleteButton = new JButton("Delete Attribute");
        deleteButton.addActionListener(new DeleteAttributeListener(attIndex, elem, this));
        deleteButtons.add(deleteButton);
        attributesPanel.add(deleteButton);

        attributesPanel.updateUI();

        editorView.startObserving();
    }

    /**
     * Add a default attribute
     */
    public void addAttribute() {
        int numRows = layout.getRows();
        String attName;
        attName = DEFAULT_ATTRIBUTE_BASE_NAME + Integer.toString(numRows);
        addAttribute(attName, DEFAULT_ATTRIBUTE_VALUE);
    }

    /**
     * Get the number of attribute rows available
     * @return the number of attribute rows available
     */
    public int getNumberOfAttributeRows() {
        return attributeNameFields.size();
    }

    public void resetAttributes() {
        for (JTextField field : attributeNameFields) {
            attributesPanel.remove(field);
        }
        for (JTextField field : attributeValueFields) {
            attributesPanel.remove(field);
        }
        for (JButton button : deleteButtons) {
            attributesPanel.remove(button);
        }
        attributeNameFields.clear();
        attributeValueFields.clear();
        deleteButtons.clear();
        listeners.clear();
        layout.setColumns(NUM_COLS);
        layout.setRows(MIN_NUM_ROWS);

        attributesPanel.updateUI();
    }

    /**
     * Change the element this panel refers to
     * @param element The new element whose attributes to represent
     */
    public void setElement(Element element) {
        elem = element;
        populate();
    }

    /**
     * Depopulate all data and remove association with an element
     */
    public void unsetElement() {
        elem = null;
        resetAttributes();
    }

    /**
     * Draw the attributes for the attached element
     */
    public void populate() {
        if (elem.getNumberOfAttributes() > 0) {
            for (String attName : elem.attributeNames()) {
                String attVal = elem.getAttribute(attName);
                addAttribute(attName, attVal);
            }
        }
    }

    /**
     * Get the element associated with this panel
     */
    public Element getElement() {
        return elem;
    }
}

@@ -1484,32 +1484,41 @@
 ivate ArrayList%3C
+Monospace
 JTextField%3E attr
@@ -1548,32 +1548,41 @@
 ivate ArrayList%3C
+Monospace
 JTextField%3E attr
@@ -2371,32 +2371,41 @@
 = new ArrayList%3C
+Monospace
 JTextField%3E();%0A 
@@ -2448,16 +2448,25 @@
 rayList%3C
+Monospace
 JTextFie
@@ -3883,32 +3883,41 @@
      %7D%0A%0A        
+Monospace
 JTextField nameF
@@ -3919,32 +3919,41 @@
 nameField = new 
+Monospace
 JTextField(name,
@@ -4051,16 +4051,25 @@
         
+Monospace
 JTextFie
@@ -4088,16 +4088,25 @@
 d = new 
+Monospace
 JTextFie
@@ -5434,32 +5434,41 @@
  %7B%0A        for (
+Monospace
 JTextField field
@@ -5538,32 +5538,32 @@
 eld);%0A        %7D%0A
-
         for (JTe
@@ -5559,16 +5559,25 @@
    for (
+Monospace
 JTextFie

Change attribute fields to monospace