package DrawTop;

import java.awt.*;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.text.*;
import javax.swing.*;
import javax.swing.border.Border.*;
import menu.*;
import shape.*;
import shapeUtil.*;
import util.*;

public class DrawPanel extends JPanel implements DropTargetListener {
    private Image buffer=null;
    String viewInformation="";
    String statusInformation="";
    public static int debug=0;
    int icount=0;
    
    public DrawPanel(){
        this.setLayout(null);
        Dimension size=DrawParameters.getSheetSizeByPixel();
        double scale=1.0;
        DrawParameters.Scale=scale;
        size=new Dimension((int)(size.getWidth()*scale), (int)(size.getHeight()*scale));
        this.setPreferredSize(size);
        this.setOpaque(true);
        this.setBackground(Color.WHITE);
		this.setAutoscrolls(true);
        DropTarget dropTarget = new DropTarget(this, this); 
        this.setDropTarget(dropTarget);
    }
    
    public void update(Graphics g) {
        this.paint(g);
    }
  
    public void paint(Graphics g) {
        if(debug>0) System.out.println("DrawPanel.paint");
        this.setBuffer();
        Graphics bufferG = this.buffer.getGraphics();
        this.paintToBuffer(bufferG);
        g.drawImage(this.buffer, 0, 0, null);
      //---------------------------//  
        this.showViewInformation();
        this.showSettingInformation();
      //---------------------------//  
    }

    public void paintToBuffer(Graphics g) {
        if(debug>0) System.out.println("paintToBuffer");
        Graphics2D g2=(Graphics2D)g;
        Color currentColor=g2.getColor();
      // draw frame of the canvas 
        Dimension size=this.getPreferredSize();
        Rectangle2D bounds=new Rectangle2D.Double(0.1d, 0.1d, size.getWidth()-0.2d, size.getHeight()-0.2d);
        g2.setColor(Color.WHITE);
        g2.fill(bounds);
        g2.setColor(Color.BLACK);
        g2.draw(bounds);
      // draw shapes  
        ContainerManager containerManager=ObjectTable.getContainerManager();
        ShapeContainer[] shapeContainers=containerManager.getContainers();
        double scale=DrawParameters.getScale();
        g2.scale(scale, scale);

        for(int i=0;i<shapeContainers.length;i++){
            shapeContainers[i].drawShape(g);
        }
      //----------------------------------------------//
      // if(DrawParameters.DRAW_UNSELECTABLEAREA){
      //      DrawShapeUtil.drawUnselectableAreas(g);
      //}
      //----------------------------------------------//
        ObjectTable.getTempShapeManager("DrawPanel").drawTempShape(g);
      //---------------------------------------------------//
        ObjectTable.getSelectionLS().drawDraggedRectangle(g);
      //---------------------------------------------------//
        g2.setColor(currentColor);
        g2.scale(1d/scale, 1d/scale);
    }
    
    private void setBuffer() {
        Dimension dimension = this.getSize();
        if (buffer == null||buffer.getWidth(null)!=dimension.width
            ||buffer.getHeight(null)!=dimension.height) {
            this.buffer=this.createImage(dimension.width, dimension.height);
        }
    }
  
    private void showViewInformation(){
        PageManager pageManager=ObjectTable.getPageManager("DrawPanel");
        if(pageManager==null||pageManager.getPageList()==null) return;
        String sheetSize=DrawParameters.SheetSizeString[DrawParameters.SheetSize];
        NumberFormat nf = NumberFormat.getPercentInstance();
        String viewInfo=" "+sheetSize;
        viewInfo+=",  zoom="+nf.format(DrawParameters.Scale);
        viewInfo+=",  page="+pageManager.getCurrentPage();
        viewInfo+=" ("+String.valueOf(pageManager.getPageList().size())+")";
        if(!viewInfo.equals(this.viewInformation)) {
            GuidancePanel.showViewMessage(viewInfo);
            this.viewInformation=viewInfo;
        }
    }
    
    private void showSettingInformation(){
        String statusInfo=" Setting:  ";
        String auto_align="off";
        if(DrawParameters.AUTO_ALIGN) auto_align="on";
        statusInfo+="Auto_align="+auto_align;
        
        String enableConnector="disable";
        if(DrawParameters.ENABLE_CONNECTOR) enableConnector="enable";
        statusInfo+=",  Connector="+enableConnector;
        
        String auto_tracking_option="free direction";
        if(DrawParameters.AUTO_TRACKING_OPTION==1) 
            auto_tracking_option="keep X/Y direction";
        if(DrawParameters.AUTO_TRACKING_OPTION==2) 
            auto_tracking_option="keep any direction";
        statusInfo+=",  Auto tracking="+ auto_tracking_option;

        String enableHilighting="disable";
        if(DrawParameters.ENABLE_HIGHLIGHTING) enableHilighting="enable";
        statusInfo+=",  Hilighting="+enableHilighting;
		
		String enableDrawNodePoints = "disable";
		if (DrawParameters.DRAW_NODE_POINTS) {
			enableDrawNodePoints= "enable";
		}
		statusInfo += ",  Draw Node Points=" + enableDrawNodePoints;
		
        if(!statusInfo.equals(this.statusInformation)) {
            GuidancePanel.showSettingsMessage(statusInfo);
            this.statusInformation=statusInfo;
        }
    }

    public void repaint(String callFrom){
        if(debug>0){
			/*
            long startTime = System.currentTimeMillis();
            for(int i=0;i<1000;i++) this.repaint();
            long endTime = System.currentTimeMillis();
            double used=(double)(endTime-startTime);
            System.out.println("repaint time="+used+" microsecond"+
                    ", callFrom="+callFrom+", count="+(icount++));
			*/
			System.out.println("repaint callFrom="+callFrom);
        } 
		//this.requestFocus();
        this.repaint();
    }
    
    public void drop(DropTargetDropEvent e) {
        if (e.isDataFlavorSupported(TransferableComponent.componentFlavor)) {
            e.acceptDrop(DnDConstants.ACTION_COPY);
        }else{
            e.rejectDrop();
            return;
        }
        if(debug>0) System.out.println("DrawPanel drop");
        Transferable transferable = e.getTransferable(); // Holds the dropped data
        ShapeContainer container=null;
        try {
            container=(ShapeContainer)transferable.getTransferData(TransferableComponent.componentFlavor);
        } catch (Exception ex) {
            e.dropComplete(false);
            return;
        }

        if(container==null) return;
        Point p = e.getLocation(); // Drop position?
        ComponentLibDialog dialog=ObjectTable.getComponentLibDialog();
        Point pos=SwingUtilities.convertPoint(this, p, dialog);
        Dimension dim=dialog.getSize();
        if(pos.x>=0&&pos.x<=dim.width&&pos.y>=0&&pos.y<=dim.height){
            if(debug>0) System.out.println("** Warning drop point is inside "
                    + "ComponentLibDialog drop p="+p+", pos="+pos
                    +", ComponentLibDialog size="+dim);
            e.dropComplete(false);
            return;
        }
        Rectangle2D oldBox=container.getBoundingBox();
        double x=p.getX()-0.5*oldBox.getWidth();
        double y=p.getY()-0.5*oldBox.getHeight();
        Rectangle2D newBox=new Rectangle2D.Double(x, y, oldBox.getWidth(), oldBox.getHeight());
        ContainerManager containerManager=ObjectTable.getContainerManager();
        //---------------------------------//
        containerManager.undoSetupStart();
        //---------------------------------//
            container.setSelected(true);
            //---------------------------------------------------------------//
            ConnectionUtil.moveResize(container, oldBox, newBox, false, false);
            //---------------------------------------------------------------//  
            container.setNewShapeId(containerManager, true);
            containerManager.addContainer(container);
        //------------------------------//
        containerManager.undoSetupEnd();
        //------------------------------//
        this.repaint();
        e.dropComplete(true);
    }

    public void dragEnter(DropTargetDragEvent e) {}
    public void dragExit(DropTargetEvent e) {}
    public void dropActionChanged(DropTargetDragEvent e) {}
    public void dragOver(DropTargetDragEvent e) {}

}//end of DrawPanel
