
package org.netbeans.cubeon.gcode.tasks;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.event.ChangeListener;
import org.netbeans.cubeon.common.ui.ComponentGroup;
import org.netbeans.cubeon.common.ui.ContainerGroup;
import org.netbeans.cubeon.common.ui.TaskEditor;
import org.netbeans.cubeon.common.ui.TaskEditorSupport;
import org.netbeans.cubeon.gcode.api.GCodeComment;
import org.netbeans.cubeon.tasks.spi.task.TaskEditorProvider.EditorAttributeHandler;
import org.netbeans.cubeon.tasks.spi.task.TaskElement;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import static org.openide.util.NbBundle.*;

/**
 *
 * @author Anuradha
 */
public class GCodeAttributeHandler implements EditorAttributeHandler {

    private GCodeTask task;
    private final TaskEditorSupport editorSupport;
    private final TaskEditor editor;
    private ComponentGroup descriptionGroup;
    private ComponentGroup attributesGroup;
    private ComponentGroup newCommentGroup;
    private ContainerGroup commentsGroup;
    private final GCodeTaskEditor gCodeTaskEditor;

    public GCodeAttributeHandler(GCodeTask task) {
        this.task = task;


        //Description group
        descriptionGroup = new ComponentGroup(
                getMessage(GCodeAttributeHandler.class, "LBL_Description"),
                getMessage(GCodeAttributeHandler.class, "LBL_Description_Dec"));
        descriptionGroup.setOpen(task.isLocal());

        //Attributes Group 
        attributesGroup = new ComponentGroup(getMessage(GCodeAttributeHandler.class, "LBL_Attributes"),
                getMessage(GCodeAttributeHandler.class, "LBL_Attributes_Dec"));
        //if task still local  open Attributes panel by default




        //comments
        commentsGroup = new ContainerGroup(getMessage(GCodeAttributeHandler.class, "LBL_Comments"),
                NbBundle.getMessage(GCodeAttributeHandler.class, "LBL_Comments_Dec"));
        commentsGroup.setOpen(false);
        //new comment group
        newCommentGroup = new ComponentGroup(getMessage(GCodeAttributeHandler.class, "LBL_New_Comment"),
                getMessage(GCodeAttributeHandler.class, "LBL_New_Comment_Dec"));
        //open new comment depende on user alrady have comment
        newCommentGroup.setOpen(task.getNewComment() != null && task.getNewComment().length() != 0);

        CommentSectionDockAction commentSectionDockAction = new CommentSectionDockAction();

        commentsGroup.setToolbarActions(new Action[]{commentSectionDockAction});
        editorSupport = new TaskEditorSupport();
        editor = editorSupport.createEditor();
        editor.setLeftSideGroups(descriptionGroup, attributesGroup, commentsGroup, newCommentGroup);
        gCodeTaskEditor = new GCodeTaskEditor(editor, task);
        // attributesGroup.setOpen(task.isLocal());
        attributesGroup.setComponent(gCodeTaskEditor.getAttributesPanel());

        newCommentGroup.setComponent(gCodeTaskEditor.getNewCommentComponent());
        descriptionGroup.setComponent(gCodeTaskEditor.getDescriptionComponent());
        editor.setLeftActiveGroup(descriptionGroup);
        refresh();


    }

    public String getName() {
        return task.getDisplayName();
    }

    public String getDisplayName() {
        return GCodeTask.issueToTaskId(task);
    }

    public String getShortDescription() {
        return task.getName();
    }

    public final void addChangeListener(ChangeListener l) {

        gCodeTaskEditor.addChangeListener(l);
    }

    public final void removeChangeListener(ChangeListener l) {

        gCodeTaskEditor.removeChangeListener(l);
    }

    public List<Action> getActions() {
        return gCodeTaskEditor.getActions();
    }

    public JComponent[] getComponent() {
        JComponent component = editor.getComponent();
        component.setName(getMessage(GCodeAttributeHandler.class, "LBL_Primary_Details"));
        return new JComponent[]{component};
    }

    public void refresh() {

        gCodeTaskEditor.refresh();
        refreshComments(commentsGroup);
    }

    public TaskElement save() {

        task = gCodeTaskEditor.read();

        task.getExtension().fireStateChenged();
        return task;
    }

    private void refreshComments(ContainerGroup commentsGroup) {
        commentsGroup.clearGroups();
        final DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance();
        List<GCodeComment> codeComments = task.getComments();
        commentsGroup.setSummary("(" + codeComments.size() + ")");
        for (GCodeComment comment : codeComments) {
            StringBuffer buffer = new StringBuffer();
            buffer.append(dateFormat.format(new Date(comment.getCommentDate()))).append(" By ");
            buffer.append(comment.getAuthor());


            ComponentGroup cg = new ComponentGroup("Comment - " + comment.getCommentId(), buffer.toString());
            cg.setSummary(buffer.toString());
            JEditorPane editorPane = new JEditorPane() {

                @Override
                public void setText(String t) {
                    super.setText(t);
                    setCaretPosition(0);
                }
            };

            editorPane.setEditable(false);
            editorPane.setText(buildChangesSet(buffer, comment));
            cg.setComponent(editorPane);
            cg.setOpen(false);
            commentsGroup.addGroup(cg);
        }
        commentsGroup.refresh();
    }

    private String buildChangesSet(StringBuffer buffer, GCodeComment comment) {
        buffer.append("\n\n");
        buffer.append(comment.getComment() != null ? comment.getComment()
                : "(No comment was entered for this change.)").append("\n\n");
        if (comment.getSummary() != null) {
            buffer.append("Summary: ").append(comment.getSummary()).append("\n");
        }
        if (comment.getStatus() != null) {
            buffer.append("Status: ").append(comment.getStatus()).append("\n");
        }
        if (comment.getOwner() != null) {
            buffer.append("Owner: ").append(comment.getOwner()).append("\n");
        }
        if (comment.getCcs().size() > 0) {
            buffer.append("Cc: ");
            for (String cc : comment.getCcs()) {
                buffer.append(cc).append(" ");
            }
            buffer.append("\n");
        }
        if (comment.getLabels().size() > 0) {
            buffer.append("Labels: ");
            for (String label : comment.getLabels()) {
                buffer.append(label).append(" ");
            }
            buffer.append("\n");
        }


        return buffer.toString();
    }

    private class CommentSectionDockAction extends AbstractAction {

        public CommentSectionDockAction() {
            validate();
        }
        private boolean docked = true;

        public void validate() {
            if (docked) {
                putValue(NAME, "Undock");
                Image undock = ImageUtilities.loadImage("org/netbeans/cubeon/gcode/undock.png");
                putValue(SMALL_ICON, ImageUtilities.image2Icon(undock));
            } else {
                putValue(NAME, "Dock");
                Image dock = ImageUtilities.loadImage("org/netbeans/cubeon/gcode/dock.png");
                putValue(SMALL_ICON, ImageUtilities.image2Icon(dock));
            }
        }

        public void actionPerformed(ActionEvent e) {
            if (docked) {
                docked = false;
                validate();
                editor.setLeftSideGroups(descriptionGroup, attributesGroup, newCommentGroup);
                commentsGroup.setOpen(true);
                editor.setRightSideGroups(commentsGroup);

            } else {
                docked = true;
                validate();
                editor.setLeftSideGroups(descriptionGroup, attributesGroup, commentsGroup, newCommentGroup);
                //remove rigrt side groups 
                editor.setRightSideGroups();

            }

            editor.setLeftActiveGroup(descriptionGroup);
        }
    }
}
