// EDMO - Elektrik Dağıtım Merkezleri Otomasyonu - Merkez Cizim Modülü
// Author - A. Zerrin Kibaroğlu
// 1.00 19/06/2000
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Cizim extends JApplet {
   JLabel label;
   //Called only when this is run as an applet.
   public void init() {
	buildUI(getContentPane());
   }
   void buildUI(Container container) {
	container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
	RectangleArea rectangleArea = new RectangleArea(this);
	container.add(rectangleArea);
	label = new JLabel("Soldaki kutulardan bir şekil seçin ve o şekli sağdaki alana tıklayarak çizin.");
	container.add(label);
	// Align the left edges of the components
	rectangleArea.setAlignmentX(LEFT_ALIGNMENT);
	label.setAlignmentX(LEFT_ALIGNMENT); //unnecessary, but doesn't hurt
   } // void buildUI
   //
   // Yapılan işlemi mesaj olarak gösterme
   //
   public void updateLabel (int msgType, Point point, int choice, int xx, int yy) {
	switch (msgType) {
	   case 0: 
		switch (choice) {
		   case 1: label.setText(point.x + ", " + point.y + " koordiantlarına merkez yerleştirildi."); break;
		   case 2: label.setText(point.x + ", " + point.y + " koordinatlarına abone yerleştirildi."); break;
		   case 3: label.setText(xx + "," + yy + " ve " + point.x + "," + point.y + " koordinatları arasına düz çizgi çekildi."); break;
		   case 4: label.setText(xx + "," + yy + " ve " + point.x + "," + point.y + " koordinatları arasına kırıklı çizgi çekildi."); break;
		} // switch
		break;
	   case 1: label.setText("Çizime daha fazla nesne yerleştiremezsiniz! Yığıt doldu!"); break;
	   case 2: label.setText("Son işlem başarıyla geri alındı!"); break;
	   case 3: label.setText("Geri alınacak işlem yok! Yığıt boş!"); break;
	} // switch
   } // public void updateLabel
   //Called only when this is run as an application.
   public static void main (String[] args) {
	JFrame f = new JFrame("Cizim");
	f.addWindowListener(new WindowAdapter() {
	   public void windowClosing(WindowEvent e) {
		System.exit(0);
	   }
	});
	Cizim controller = new Cizim();
	controller.buildUI(f.getContentPane());
	f.pack();
	f.setVisible(true);
   } // public static void main
} // public class Cizim
//
// Cizim Alani nesnesi
//
class RectangleArea extends JPanel {
   static final int NOFUNC = 5; // No of functions
   static final int STACKSIZE = 50; // No of elements that can be placed
   static final int RECTWIDTH = 40; // Default element width
   static final int RECTHEIGHT = 40; // Default element height
   static final int BASEX = 0, BASEY = 0, WIDTH = 600, HEIGHT = 400;
   // Yığıt tanımlaması 
   public class Stack {
	int top;
	int[] xBas;
	int[] yBas;
	int[] sTip;
	int[] xBit;
	int[] yBit;
	public Stack() {
	   top = -1;
	   xBas = new int[STACKSIZE];
	   yBas = new int[STACKSIZE];
	   sTip = new int[STACKSIZE];
	   xBit = new int[STACKSIZE];
	   yBit = new int[STACKSIZE];
	} // public Stack()
	// Yığıta şekil elemanı yerleştirme (yalnızca tek koordinat)
	public boolean push(int x, int y, int st) {
	   if (top < STACKSIZE-1) {
		top++;
		xBas[top]=x;
		yBas[top]=y;
		sTip[top]=st;
		xBit[top]=0;
		yBit[top]=0;
	   } // if
	   return (top < STACKSIZE);
	} // public boolean push
	// Yığıta çizgi (hat) yerleştirme (başlangıç ve bitiş koordinatı)
	public void push(int x, int y, int st, int x2, int y2) {
	   if (top < STACKSIZE-1) {
		top++;
		xBas[top]=x;
		yBas[top]=y;
		sTip[top]=st;
		xBit[top]=x2;
		yBit[top]=y2;
		controller.updateLabel(0,point,st,bx,by);
	   }
	   else controller.updateLabel(1,point,st,bx,by);
	} // public void push
	// Yığıttan eleman alma (silme)
	public void pop() {
	   boolean popped = (top > -1);
	   if (popped) {
		top--;
		controller.updateLabel(2,point,choice,bx,by);
	   } // if
	   else controller.updateLabel(3,point,choice,bx,by);
	} // public void pop
	// Yığıttaki elemanları çizim alanına çizma
	public void drawElements(Graphics g) {
	   g.fillRect(BASEX + 1, BASEY + (choice-1) * RECTHEIGHT + 1, RECTWIDTH - 1, RECTHEIGHT - 1);
	   for (int i=0; i<=top; i++) 
	   switch (sTip[i]) {
		// Merkez şekli çiz
		case 1: 
		   g.drawRect(xBas[i], yBas[i], RECTWIDTH, RECTHEIGHT);
		   g.drawLine(xBas[i], yBas[i], xBas[i]+RECTWIDTH, yBas[i]+RECTHEIGHT/2);
		   g.drawLine(xBas[i], yBas[i]+RECTHEIGHT, xBas[i]+RECTWIDTH, yBas[i]+RECTHEIGHT/2);
		   break;
		// Abone şekli çiz (kare)
		case 2:
		   g.drawRect(xBas[i], yBas[i], RECTWIDTH, RECTHEIGHT);
		   break;
		// Doğru çizgi (hat) çiz
		case 3:
		   g.drawLine(xBas[i], yBas[i], xBit[i], yBit[i]);
		   break;
		// Kırıklı çizgi (hat) çiz
		case 4:
		   int xOrt = (xBas[i]+xBit[i]) / 2;
		   g.drawLine(xBas[i], yBas[i], xOrt, yBas[i]);
		   g.drawLine(xOrt, yBas[i], xOrt, yBit[i]);
		   g.drawLine(xOrt, yBit[i], xBit[i], yBit[i]);
		   break;
	    } //switch
	} // public void drawElements
   } // public class Stack
   Point point = null;
   Point basPoint = null;
   int bx, by;
   Cizim controller;
   int choice = 0;
   boolean firstPoint = false;
   Stack bizimStack = new Stack();
   Dimension preferredSize = new Dimension(WIDTH,HEIGHT);
   public RectangleArea(Cizim controller) {
	this.controller = controller;
	Border raisedBevel = BorderFactory.createRaisedBevelBorder();
	Border loweredBevel = BorderFactory.createLoweredBevelBorder();
	Border compound = BorderFactory.createCompoundBorder (raisedBevel, loweredBevel);
	setBorder(compound);
	addMouseListener(new MouseAdapter() {
         public void mousePressed(MouseEvent e) {
		int x = e.getX();
		int y = e.getY();
		if (point == null) {
		   point = new Point(x, y);
		}
		else {
		   point.x = x;
		   point.y = y;
		}
		repaint();
	   } // public void mousePressed
	}); // addMouseListener
   } // public RectangleArea
    public Dimension getPreferredSize() {
        return preferredSize;
    }
   public void paintComponent(Graphics g) {
	super.paintComponent(g);  //paint background
	g.drawLine(BASEX+RECTWIDTH,BASEY,BASEX+RECTWIDTH,BASEY+HEIGHT);
	for (int i=1; i<=NOFUNC; i++)
	   g.drawLine(BASEX,BASEY+RECTHEIGHT*i,BASEX+RECTWIDTH,BASEY+RECTHEIGHT*i);
	g.drawString("A",17,28);
	g.drawString("B",17,68);
	g.drawString("C",17,108);
	g.drawString("D",17,148);
	g.drawString("E",17,188);
	if (point != null) {
	   if (point.x <= 40) {
		if (point.y <= 160) {
		   choice = point.y / 40 + 1;
		}
		if (point.y > 160 && point.y <= 200) {
		   bizimStack.pop();
		}
	   }
	   else if (point.x > 40) {
		switch (choice) {
		   case 1: 
			bizimStack.push(point.x,point.y,choice);
			break;
		   case 2:
			bizimStack.push(point.x,point.y,choice);
			break;
		   case 3: 
			if (firstPoint) {
			   bizimStack.push(bx, by, choice, point.x, point.y);
			   firstPoint = false;
			}
			else {
			   bx = point.x;
			   by = point.y;
			   firstPoint = true;
			}
			break;
		   case 4: 
			if (firstPoint) {
			   bizimStack.push(bx, by, choice, point.x, point.y);
			   firstPoint = false;
			}
			else {
			   bx = point.x;
			   by = point.y;
			   firstPoint = true;
			}
			break;
		} //switch
	   } //else
	   bizimStack.drawElements(g);
	} //if point != null
   } // public RectangleArea
} // class RectangleArea