/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package util;

import java.text.*;
import javax.swing.undo.*;
import textBox.*;
import DrawTop.*;
import shape.*;

public class UndoableDrawEdit extends AbstractUndoableEdit{

    //static int debug=0;
    public UndoableDrawEdit(){}
    
//Delimiter
    public static class Delimiter extends AbstractUndoableEdit{
        int debug=0;
        public Delimiter(){}

        public String getUndoPresentationName(){
            return "Delimiter";
        }
        public String getRedoPresentationName(){
            return "Delimiter";
        }
        public boolean isSignificant() {
            return true;
        }

        public void undo() throws CannotUndoException {
            super.undo();
        }

        public void redo() throws CannotRedoException {
            super.redo();
        }
        public String toString() {
            String str="Delimiter";
            return str;
        }
    }// Delmiter


//ChangeContainer
    public static class ChangeContainer extends AbstractUndoableEdit{
        SerializableElement oldData=null;
        SerializableElement newData=null;
        int debug=0;
        public ChangeContainer(ShapeContainer oldContainer, ShapeContainer newContainer){
            SerializableElement sElement
                    =SerializableElementUtil.convertShapeContainer(oldContainer);
            this.oldData=sElement;
            sElement=SerializableElementUtil.convertShapeContainer(newContainer);
            this.newData=sElement;
            if(debug>0){
                    String oldDataStr="null";
                    String newDataStr="null";
                    if(oldData!=null) oldDataStr=oldData.toString();
                    if(newData!=null) newDataStr=newData.toString();
                    System.out.println(" ** UndoDrawEdit.ChangeContainer" +
                        "\n  -- oldData="+oldDataStr+"\n  -- newData="+newDataStr);
            }
            if(oldData==null||newData==null){
                System.err.println("*** Error UndoableDrawEdit.ChangeContainer" +
                        " Null data !");
                    String oldDataStr="null";
                    String newDataStr="null";
                    if(oldData!=null) oldDataStr=oldData.toString();
                    if(newData!=null) newDataStr=newData.toString();
                    System.out.println(" ** UndoDrawEdit.ChangeContainer" +
                        "\n  -- oldData="+oldDataStr+"\n  -- newData="+newDataStr);
            return;
            }
        }

        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "ChangeContainer Undo";
        }
        public String getRedoPresentationName(){
            return "ChangeContainer Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        
        public void undo(){
            ContainerManager manager=ObjectTable.getContainerManager("UndoableDrawEdit");
                ShapeContainer container=manager.getContainer(this.oldData.shapeId);
                SerializableElementUtil.setToShapeContainer(this.oldData, container);
                //manager.deSelectAll();
                container.setSelected(true);
                if(debug>0) System.out.println(" ** UndoDrawEdit.ChangeContainer" +
                        ", undo="+container.getShapeId());
        }
        
        public void redo(){
            ContainerManager manager=ObjectTable.getContainerManager("UndoableDrawEdit");
                ShapeContainer container=manager.getContainer(this.newData.shapeId);
                SerializableElementUtil.setToShapeContainer(this.newData, container);
                //manager.deSelectAll();
                container.setSelected(true);
                if(debug>0) System.out.println(" ** UndoDrawEdit.ChangeContainer" +
                        ", redo="+container.getShapeId());
        }
    }
    
    public static class CreateContainer extends AbstractUndoableEdit{
        SerializableElement data=null;
        int debug=0;
        
        public CreateContainer(ShapeContainer container){
            SerializableElement sElement
                    =SerializableElementUtil.convertShapeContainer(container);
            this.data=sElement;
            if(debug>0) System.out.println("UndoDrawEdit.CreateContainer constructor container="
					+container.toShortString());

        }
        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "CreateContainer Undo";
        }
        public String getRedoPresentationName(){
            return "CreateContainer Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        public void undo(){
            ContainerManager manager=ObjectTable.getContainerManager("UndoableDrawEdit");
            boolean removed=false;
            removed=manager.deleteContainer(data.shapeId);
            if(!removed) {
                System.err.println("*** Error UndoDrawEdit.CreateContainer" +
                        ", undo delete failed  shape="+data.shapeId);
            }
            if(debug>0) System.out.println(" ** UndoDrawEdit.CreateContainer" +
                        ", undo, deleteContainer="+data.shapeId);
        }
        public void redo(){
            ShapeContainer container
                    =SerializableElementUtil.invertShapeContainer(this.data);
            ContainerManager manager=ObjectTable.getContainerManager("UndoableDrawEdit");
            manager.addContainer(container.getContainerIndex(), container);
            //manager.deSelectAll();
            container.setSelected(true);
            if(debug>0) System.out.println(" ** UndoDrawEdit.CreateContainer" +
                        ", redo addContainer="+container.getShapeId());
            container.setSelected(true);
        }
    } //end of DeleteContainer
    

    public static class DeleteContainer extends AbstractUndoableEdit{
        SerializableElement data=null;
        boolean significant=true;
        int debug=0;
        
        public DeleteContainer(ShapeContainer container){
            SerializableElement sElement=
                    SerializableElementUtil.convertShapeContainer(container);
            this.data=sElement;
            if(debug>0) System.out.println("UndoDrawEdit.DeleteContainer constructor data="+this.data.toShortString());
        }
        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "DeleteContainer Undo";
        }
        public String getRedoPresentationName(){
            return "DeleteContainer Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        public void undo(){
            ShapeContainer container
                    =SerializableElementUtil.invertShapeContainer(this.data);
            ContainerManager manager=ObjectTable.getContainerManager("UndoableDrawEdit");
            manager.addContainer(container.getContainerIndex(), container);
            //manager.deSelectAll();
            container.setSelected(true);
            if(debug>0) System.out.println(" ** UndoDrawEdit.DeleteContainer" +
                        ", undo addContainer="+container.getShapeId());
        }
        
        public void redo(){
            ContainerManager manager=ObjectTable.getContainerManager("UndoableDrawEdit");
            boolean removed = false;
            removed = manager.deleteContainer(data.shapeId);
            if (!removed) {
                System.err.println("*** Error in  UndoDrawEdit.CreateContainer:"
                        + " redo delete failed  shape=" + data.shapeId);
            }
            if(debug>0) System.out.println(" ** UndoDrawEdit.DeleteContainer" +
                        ", redo deleteContainer="+data.shapeId);
        }
    } //end of DeleteContainer
    
//Change AttributedString
    public static class ChangeTextBox extends AbstractUndoableEdit{
        String shapeId="";
        public SerializableTextBox oldTextBox=null;
        public SerializableTextBox newTextBox=null;

        int debug=0;
        
        public ChangeTextBox(String shapeId, TextBox oldTextBox, TextBox newTextBox){
            this.shapeId=shapeId;
            this.oldTextBox=oldTextBox.getSerializableTextBox();
            this.newTextBox=newTextBox.getSerializableTextBox();
        }

        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "ChangeTextBox Undo";
        }
        public String getRedoPresentationName(){
            return "ChangeTextBox Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        public void undo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer targetContainer=containerManager.getContainer(this.shapeId);
            if(targetContainer==null||!targetContainer.isTextBox()){
                System.err.println("*** Error UndoableDrawEdit.ChangeText.undo; targetContainer not found");
                return;
            }
            TextBox textBox=targetContainer.getTextBox();
            textBox.setSerializableTextBox(this.oldTextBox);
            if(debug>0) System.out.println("*** ChangeTextBox.undo shapeId="+this.oldTextBox.shapeId);
        }

        public void redo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer targetContainer=containerManager.getContainer(this.shapeId);
            if(targetContainer==null||!targetContainer.isTextBox()){
                System.err.println("*** Error UndoableDrawEdit.ChangeText.redo; targetContainer not found");
                return;
            }
            TextBox textBox=targetContainer.getTextBox();
            textBox.setSerializableTextBox(this.newTextBox);
            if(debug>0) System.out.println("*** ChangeTextBox.redo shapeId="+this.newTextBox.shapeId);
        }
    } //End of InsertText
    
//Change AttributedString
    public static class ChangePaintStyle extends AbstractUndoableEdit{
        String shapeId="";
        public SerializablePaintStyle oldPaintStyle=null;
        public SerializablePaintStyle newPaintStyle=null;
        int debug=0;
        
        public ChangePaintStyle(String shapeId, PaintStyle oldPaintStyle, 
                PaintStyle newPaintStyle){
            this.shapeId=shapeId;
            this.oldPaintStyle=oldPaintStyle.getSerializablePaintStyle();
            this.newPaintStyle=newPaintStyle.getSerializablePaintStyle();
        }

        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "ChangePaintStyle Undo";
        }
        public String getRedoPresentationName(){
            return "ChangePaintStyle Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        public void undo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer targetContainer=containerManager.getContainer(this.shapeId);
            PaintStyle paintStyle=targetContainer.getPaintStyle();
            paintStyle.setSerializablePaintStyle(this.oldPaintStyle);
            if(debug>0) System.out.println("*** ChangePaintStyle.undo shapeId="+this.oldPaintStyle.shapeId);
        }

        public void redo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer targetContainer=containerManager.getContainer(this.shapeId);
            PaintStyle paintStyle=targetContainer.getPaintStyle();
            paintStyle.setSerializablePaintStyle(this.newPaintStyle);
            if(debug>0) System.out.println("*** ChangePaintStyle.redo shapeId="+this.newPaintStyle.shapeId);
        }
    } //End of InsertText
 
    
//Change AttributedString
    public static class ChangeText extends AbstractUndoableEdit{
        //ContainerManager containerManager=ObjectTable.getContainerManager("UndoableDrawEdit");
        String shapeId="";
        AttributedString oldStr=null;
        AttributedString newStr=null;
        int position=0;
        int debug=0;
        
        public ChangeText(String shapeId, AttributedString oldStr,
                AttributedString newStr){
            this.shapeId=shapeId;
            this.oldStr=oldStr;
            this.newStr=newStr;
            if(debug>0) System.out.println(" ** UndoableDrawEdit.ChangeText" +
                    "  oldStr="+Util.Text(oldStr)+"  newStr="+Util.Text(newStr));
        }
        
        public ShapeContainer getContainer(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer container=containerManager.getContainer(this.shapeId);
            return (ShapeContainer)container;
        }
        
        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "ChangeText Undo";
        }
        public String getRedoPresentationName(){
            return "ChangeText Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        public void undo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer container=containerManager.getContainer(this.shapeId);
            ShapeContainer shapeContainer=(ShapeContainer)container;
            TextBox textBox=shapeContainer.getTextBox();
            if(textBox==null){
                System.err.println("*** Error UndoableDrawEdit.ChangeText.undo; textBox not found");
                return;
            } else{
                shapeContainer.getTextBox().replaceText(TextBox.UNDO_REDO, this.oldStr);
                if(debug>0) System.out.println(" ** UndoableDraeEdit.InsertText.undo" +
                    "  attribStr="+Util.Text(oldStr));
            }
        }

        public void redo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer container=containerManager.getContainer(this.shapeId);
            ShapeContainer shapeContainer=(ShapeContainer)container;
            TextBox textBox=shapeContainer.getTextBox();
            if(textBox==null){
                System.err.println("*** Error UndoableDrawEdit.ChangeText.undo; textBox not found");
                return;
            } else{
                shapeContainer.getTextBox().replaceText(TextBox.UNDO_REDO, this.newStr);
            }
        }
    } //End of InsertText
    
//insert AttributedString
    public static class InsertText extends AbstractUndoableEdit{
        String shapeId="";
        AttributedString attribStr=null;
        int position=0;
        int debug=0;
        
        public InsertText(String shapeId, AttributedString attribStr,
                int position){
            this.shapeId=shapeId;
            this.attribStr=attribStr;
            this.position=position;
            if(debug>0) System.out.println(" ** UndoableDraeEdit.InsertText" +
                    "  attribStr="+Util.Text(attribStr));
        }

        public ShapeContainer getContainer(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer container=containerManager.getContainer(this.shapeId);
            return (ShapeContainer)container;
        }

        public int getPosition(){
            return this.position;
        }
        public void setPosition(int position){
            this.position=position;
        }
        public AttributedString getAttribString(){
            return this.attribStr;
        }
        public void setAttribString(AttributedString attribStr){
            if(debug>0) System.out.println(" ** UndoableDraeEdit.InsertText.setAttribString" +
                    "  attribStr="+Util.Text(attribStr));
            this.attribStr=attribStr;
        }
        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "InsertText Undo";
        }
        public String getRedoPresentationName(){
            return "InsertText Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        public void undo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer shapeContainer=containerManager.getContainer(this.shapeId);
            TextBox textBox=shapeContainer.getTextBox();
            if(textBox==null){
                System.err.println("*** Error UndoableDrawEdit.DeleteText.undo; textBox not found");
                return;
            } else{
                int length=this.attribStr.getIterator().getEndIndex();
                shapeContainer.getTextBox().deleteText(TextBox.UNDO_REDO, this.position, 
                        this.position+length);
                if(debug>0) System.out.println(" ** UndoableDraeEdit.InsertText.undo" +
                    "  attribStr="+Util.Text(attribStr));
            }
        }

        public void redo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer shapeContainer=containerManager.getContainer(this.shapeId);
            TextBox textBox=shapeContainer.getTextBox();
            if(textBox==null){
                System.err.println("*** Error UndoableDrawEdit.DeleteText.undo; textBox not found");
                return;
            } else{
                shapeContainer.getTextBox().insertText(TextBox.UNDO_REDO, 
                        this.position, this.attribStr.getIterator());
            }
        }
    } //End of InsertText
    
//delete AttributedString
    public static class DeleteText extends AbstractUndoableEdit{
        //ContainerManager containerManager=ObjectTable.getContainerManager("UndoableDrawEdit");
        String shapeId="";
        AttributedString attribStr=null;
        int position=0;
        //boolean significant=true;
        int debug=0;
        public DeleteText(String shapeId, AttributedString attribStr,
                int position){
            this.shapeId=shapeId;
            this.attribStr=attribStr;
            this.position=position;
            if(debug>0) System.out.println(" ** UndoableDraeEdit.DeleteText" +
                    "  attribStr="+Util.Text(attribStr));
        }

        public ShapeContainer getContainer(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer container=containerManager.getContainer(this.shapeId);
            return (ShapeContainer)container;
        }

        public int getPosition(){
            return this.position;
        }
        public void setPosition(int position){
            this.position=position;
        }
        public AttributedString getAttribString(){
            return this.attribStr;
        }
        public void setAttribString(AttributedString attribStr){
            if(debug>0) System.out.println(" ** UndoableDraeEdit.DeleteText.setAttribString" +
                    "  attribStr="+Util.Text(attribStr));
            this.attribStr=attribStr;
        }
        public boolean canUndo(){
            return true;
        }
        public boolean canRedo(){
            return true;
        }
        public String getUndoPresentationName(){
            return "DeleteText Undo";
        }
        public String getRedoPresentationName(){
            return "DeleteText Redo";
        }
        public boolean isSignificant(){
            return true;
        }
        public void undo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer container=containerManager.getContainer(this.shapeId);
            ShapeContainer shapeContainer=(ShapeContainer)container;
            TextBox textBox=shapeContainer.getTextBox();
            if(textBox==null){
                System.err.println("*** Error UndoableDrawEdit.DeleteText.undo; textBox not found");
                return;
            } else{
                shapeContainer.getTextBox().insertText(TextBox.UNDO_REDO, this.position, 
                        this.attribStr.getIterator());
            if(debug>0) System.out.println(" ** UndoableDraeEdit.DeleteText.undo" +
                    "  attribStr="+Util.Text(attribStr));
            }
        }
        public void redo(){
            ContainerManager containerManager=ObjectTable.getContainerManager();
            ShapeContainer container=containerManager.getContainer(this.shapeId);
            ShapeContainer shapeContainer=(ShapeContainer)container;
            TextBox textBox=shapeContainer.getTextBox();
            if(textBox==null){
                System.err.println("*** Error UndoableDrawEdit.DeleteText.undo; textBox not found");
                return;
            } else{
                int length=this.attribStr.getIterator().getEndIndex();
                shapeContainer.getTextBox().deleteText(TextBox.UNDO_REDO, this.position, 
                        this.position+length);
            }
        }
    }//End of DeleteText
    
}//UndoableDrawEdit
