package cnp.ew.kdemo;

import java.awt.*;
import java.util.*;
import cnp.ew.spin.*;
import cnp.ew.util.*;
import cnp.ew.layout.*;
import cnp.ew.misc.*;
import cnp.ew.lightweight.*;
import cnp.ew.text.*;

public class CpAttachmentEditorPanel extends CpLcPanel
{
	 public static final int ATTACHMENT_TOP=0;
	 public static final int ATTACHMENT_LEFT=1;
	 public static final int ATTACHMENT_BOTTOM=2;
	 public static final int ATTACHMENT_RIGHT=3;

    int editedAttachment;
    CpLightweightComponent editedLc;
    CpAttachments attachments;
    Vector siblings;
    boolean settingAttachments=false;

    Label attachmentTypeLabel, siblingLabel, valueLabel;
    Choice attachmentTypeChoice;
    Choice siblingChoice;
    CpIntegerSpinEditor valueSpinButton;

    public CpAttachmentEditorPanel(int newEditedAttachment)
    {
        editedAttachment = newEditedAttachment;

        addLc();
        addAttachmentTypeChoice();
        addValueSpinButton();
        addLabels();

    }

    void addAttachmentTypeChoice()
    {
        attachmentTypeChoice = new Choice();
        attachmentTypeChoice.addItem("Attached To Parent " + getSameSide());
        attachmentTypeChoice.addItem("Attached To Parent " + getOppositeSide());
        attachmentTypeChoice.addItem("Attached To Sibling " + getOppositeSide());
        attachmentTypeChoice.addItem("Attached To Sibling " + getSameSide());
        attachmentTypeChoice.addItem("Use Offset As Parent Percentage");
        attachmentTypeChoice.addItem("Use Offset As " + getDimension());
        attachmentTypeChoice.addItem("Use Preferred Size");
        attachmentTypeChoice.addItem("Center Relative To Parent");
        attachmentTypeChoice.addItem("Center Relative To Sibling");
        attachmentTypeChoice.setBackground(Color.white);
        add(attachmentTypeChoice);
    }

    void addValueSpinButton()
    {
        valueSpinButton = new CpIntegerSpinEditor();
        add(valueSpinButton);
    }

    void addLc()
    {
        CpPanelLc panelLc = new CpPanelLc();
        setLc(panelLc);
        panelLc.setBorderStyle(CpAbstractLc.BORDER_LABELED_RAISED);
        panelLc.setText(getAttachmentLabel());
    }

    void addLabels()
    {
        attachmentTypeLabel = new Label("Style");
        add(attachmentTypeLabel);

        siblingLabel = new Label("Sibling");
        add(siblingLabel);

        valueLabel = new Label("Offset");
        add(valueLabel);
    }


    public void layout()
    {

        super.layout();

        if (siblingChoice == null) {
            return;
        }

        Dimension labelPS;
        Dimension choicePS;
        Dimension spinPS;
        int labelTop;
        int choiceTop;
        int spinTop;
        int labelGap = 4;
        int gap = 5;
        Insets insets = insets();
        int left = insets.left + labelGap;
        int height = size().height - insets.top - insets.bottom;

        choicePS = attachmentTypeChoice.preferredSize();
        labelPS = attachmentTypeLabel.preferredSize();
        spinPS = valueSpinButton.preferredSize();

        choiceTop = insets.top + (height - choicePS.height) / 2;
        spinTop = insets.top + (height - spinPS.height) / 2;
        labelTop = insets.top + (height - labelPS.height) / 2;

        attachmentTypeLabel.reshape(left, labelTop, labelPS.width, labelPS.height);
        left += labelPS.width + labelGap;
        attachmentTypeChoice.reshape(left, choiceTop, choicePS.width, choicePS.height);
        left += choicePS.width + gap;

        labelPS = siblingLabel.preferredSize();
        choicePS = siblingChoice.preferredSize();
        siblingLabel.reshape(left, labelTop, labelPS.width, labelPS.height);
        left += labelPS.width + labelGap;
        siblingChoice.reshape(left, choiceTop, choicePS.width, choicePS.height);
        left += choicePS.width + gap;

        labelPS = valueLabel.preferredSize();
        valueLabel.reshape(left, labelTop, labelPS.width, labelPS.height);
        left += labelPS.width + labelGap;
        valueSpinButton.reshape(left, spinTop, spinPS.width, spinPS.height);
    }

    public void setAttachments(CpAttachments attachments, Vector siblings, CpLightweightComponent editedLc)
    {
        this.attachments = attachments;
        this.siblings = siblings;
        this.editedLc = editedLc;

        settingAttachments = true;
        attachmentTypeChoice.select(getIndexForAttachmentsType());
        refreshSiblingChoice();
        siblingChoice.select(getIndexForSiblingType());
        valueSpinButton.setValue(getValue());
        layout();
        settingAttachments = false;
    }

    void refreshSiblingChoice()
    {
        CpReadOnlyTextAreaLc sibling;
        if (siblingChoice == null) {
            siblingChoice = new Choice();
            add(siblingChoice);
            siblingChoice.setBackground(Color.white);
            siblingChoice.addItem("None");
            for (int i=0; i < siblings.size(); i++) {
                sibling = (CpReadOnlyTextAreaLc)siblings.elementAt(i);
                siblingChoice.addItem(sibling.getText());
            }
        }
    }

    int getIndexForAttachmentsType()
    {
        int attachmentType=0;

        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            attachmentType = attachments.topAttachmentType;
            break;
        case ATTACHMENT_BOTTOM:
            attachmentType = attachments.bottomAttachmentType;
            break;
        case ATTACHMENT_LEFT:
            attachmentType = attachments.leftAttachmentType;
            break;
        case ATTACHMENT_RIGHT:
            attachmentType = attachments.rightAttachmentType;
            break;
        }

        switch (attachmentType) {
        case CpAttachments.ATTACH_PARENT:
            return 0;
        case CpAttachments.ATTACH_PARENT_OPPOSITE:
            return 1;
        case CpAttachments.ATTACH_SIBLING:
            return 2;
        case CpAttachments.ATTACH_SIBLING_OPPOSITE:
            return 3;
        case CpAttachments.ATTACH_POSITION:
            return 4;
        case CpAttachments.ATTACH_SELF:
            return 5;
        case CpAttachments.ATTACH_NONE:
            return 6;
        case CpAttachments.CENTER_PARENT:
            return 7;
        case CpAttachments.CENTER_SIBLING:
            return 8;
        }

        return -1;
    }

    int getIndexForSiblingType()
    {
        CpLightweightComponent sibling=null;
        int index;

        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            sibling = attachments.topSibling;
            break;
        case ATTACHMENT_BOTTOM:
            sibling = attachments.bottomSibling;
            break;
        case ATTACHMENT_LEFT:
            sibling = attachments.leftSibling;
            break;
        case ATTACHMENT_RIGHT:
            sibling = attachments.rightSibling;
            break;
        }

        if (sibling == null) {
            return 0;
        }
        index = 1;
        while (index < siblings.size()) {
            if (sibling == siblings.elementAt(index - 1)) {
                return index;
            }
            index++;
        }
        return -1;
    }

    int getValue()
    {
        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            return attachments.topOffset;
        case ATTACHMENT_BOTTOM:
            return attachments.bottomOffset;
        case ATTACHMENT_LEFT:
            return attachments.leftOffset;
        case ATTACHMENT_RIGHT:
            return attachments.rightOffset;
        }
        return -1;
    }


    String getAttachmentLabel()
    {
        return getSameSide();
    }

    String getSameSide()
    {
        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            return "Top";
        case ATTACHMENT_BOTTOM:
            return "Bottom";
        case ATTACHMENT_LEFT:
            return "Left";
        case ATTACHMENT_RIGHT:
            return "Right";
        }

        return null;
    }

    String getOppositeSide()
    {
        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            return "Bottom";
        case ATTACHMENT_BOTTOM:
            return "Top";
        case ATTACHMENT_LEFT:
            return "Right";
        case ATTACHMENT_RIGHT:
            return "Left";
        }

        return null;
    }

    String getDimension()
    {
        switch (editedAttachment) {
        case ATTACHMENT_TOP:
        case ATTACHMENT_BOTTOM:
            return "Height";
        case ATTACHMENT_LEFT:
        case ATTACHMENT_RIGHT:
            return "Width";
        }

        return null;
    }

    public boolean handleEvent(Event e)
    {
        if (e.target == attachmentTypeChoice && e.id == Event.ACTION_EVENT) {
            updateAttachments();
        }
        if (e.target == siblingChoice && e.id == Event.ACTION_EVENT) {
            updateAttachments();
        }
        if (e.target == valueSpinButton && e.id == CpEvent.OBJECT_CHANGED) {
            updateAttachments();
        }
        return super.handleEvent(e);
    }

    void updateAttachments()
    {
        // we're getting events when we set the values programmatically, and we don't want
        // to be setting the values in the attachments based on the controls when they're only
        // partially set (e.g. one choice is set, but a second has not yet been set).
        if (settingAttachments) {
            return;
        }

        setAttachmentsType();
        setAttachmentsSibling();
        setAttachmentsOffset();
        postEvent(new Event(this, CpEvent.ATTACHMENTS_CHANGED, null));
    }

    void setAttachmentsType()
    {
        int attachmentType=0;

        switch (attachmentTypeChoice.getSelectedIndex()) {
        case 0:
            attachmentType = CpAttachments.ATTACH_PARENT;
            break;
        case 1:
            attachmentType = CpAttachments.ATTACH_PARENT_OPPOSITE;
            break;
        case 2:
            attachmentType = CpAttachments.ATTACH_SIBLING;
            break;
        case 3:
            attachmentType = CpAttachments.ATTACH_SIBLING_OPPOSITE;
            break;
        case 4:
            attachmentType = CpAttachments.ATTACH_POSITION;
            break;
        case 5:
            attachmentType = CpAttachments.ATTACH_SELF;
            break;
        case 6:
            attachmentType = CpAttachments.ATTACH_NONE;
            break;
        case 7:
            attachmentType = CpAttachments.CENTER_PARENT;
            break;
        case 8:
            attachmentType = CpAttachments.CENTER_SIBLING;
            break;
        }


        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            attachments.topAttachmentType = attachmentType;
            break;
        case ATTACHMENT_BOTTOM:
            attachments.bottomAttachmentType = attachmentType;
            break;
        case ATTACHMENT_LEFT:
            attachments.leftAttachmentType = attachmentType;
            break;
        case ATTACHMENT_RIGHT:
            attachments.rightAttachmentType = attachmentType;
            break;
        }
    }

    void setAttachmentsSibling()
    {
        int index = siblingChoice.getSelectedIndex();
        CpLightweightComponent sibling;

        if (index <= 0) {
            sibling = null;
        } else {
            sibling = (CpLightweightComponent)siblings.elementAt(index - 1);
        }

        if (sibling == editedLc) {
            sibling = null;
        }

        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            attachments.topSibling = sibling;
            break;
        case ATTACHMENT_BOTTOM:
            attachments.bottomSibling = sibling;
            break;
        case ATTACHMENT_LEFT:
            attachments.leftSibling = sibling;
            break;
        case ATTACHMENT_RIGHT:
            attachments.rightSibling = sibling;
            break;
        }
    }

    void setAttachmentsOffset()
    {
        int offset = valueSpinButton.getIntValue();

        switch (editedAttachment) {
        case ATTACHMENT_TOP:
            attachments.topOffset = offset;
            break;
        case ATTACHMENT_BOTTOM:
            attachments.bottomOffset = offset;
            break;
        case ATTACHMENT_LEFT:
            attachments.leftOffset = offset;
            break;
        case ATTACHMENT_RIGHT:
            attachments.rightOffset = offset;
            break;
        }
    }
}







