// A.Krzysztof Kwasniewski's Cobweb posets 
// Aplication draws layers of Cobweb posets' Hasse diagram
// author: Maciej Dziemianczuk, 
// www.dejaview.cad.pl/cobwebposets.html


import java.awt.*;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.applet.Applet;


class CVertex
{
	// position on the screen
	int x;
	int y;
	
	static int _RADIUS = 10;
	
	public CVertex(int _x, int _y)
	{
		x = _x;
		y = _y;
	}
	
	public void draw(Graphics g)
	{
		if (y > 20)
		g.fillOval(x, y, _RADIUS, _RADIUS);
	}
	
	public void draw_chain(Graphics g, CVertex to)
	{
		if (to.y > 20)
		g.drawLine(x+_RADIUS/2, y+_RADIUS/2, to.x+_RADIUS/2, to.y+_RADIUS/2);
	}
}

//---------------------------------------------------------------------
class CobwebGraph extends java.applet.Applet
{
	int K;
	int N;
	int M;
	int Seq;
	
	int _HEIGHT;
	int _WIDTH;
	
	int _SPACE_X = 30;
	int _SPACE_Y = 30;
	
	// table of vertices (N-K)xN
	CVertex [] [] Cobweb;
	
	int SeqArr [];
	
	//-----------------------------------------------------------------
	public CobwebGraph( int _k, int _n, int _seq, int _width, int _height)
	{
		K = _k;
		N = _n;
		M = N - K;
		Seq = _seq;
		_WIDTH = _width;
		_HEIGHT = _height - 60;
	}
	
	//-----------------------------------------------------------------
	public void paint( Graphics g )
	{        
		Rectangle r = getBounds();
		g.clearRect( 0, 0, r.width, r.height );
		g.setColor( Color.black );
		
		createSequence ();
		
		createCobweb (g);
        
		drawCobweb (g);
	}
	
	//-----------------------------------------------------------------
	void createSequence ()
	{
		SeqArr = new int [N+1];
		
		// Natural numbers
		if (Seq == 1)
		{
			for (int i=0; i<=N; ++i)
			{
				SeqArr[i] = i;
			}
		}
		
		// Fibonacci numbers
		if (Seq == 2)
		{
			SeqArr[0] = 0;
			SeqArr[1] = 1;
			
			for (int i=2; i<=N; ++i)
			{
				SeqArr[i] = SeqArr[i-1] + SeqArr[i-2];
			}
			
		}
		
		// Even natural numbers
		if (Seq == 3)
		{
			for (int i=0; i<=N; ++i)
			{
				SeqArr[i] = i*2;
			}
		}
		
		// nF = 2^n
		if (Seq == 4)
		{
			SeqArr[0] = 1;
			SeqArr[1] = 1;
			for (int i=2; i<=N; ++i)
			{
				SeqArr[i] = SeqArr[i-1] * 2;
			}
		}
		
		// nF = mF + kF where 1F = 3;
		if (Seq == 5)
		{
			SeqArr[0] = 0;
			SeqArr[1] = 3;
			for (int i=2; i<=N; ++i)
			{
				SeqArr[i] = SeqArr[i-1] + SeqArr[1];
			}
			
		}
		
		// nF = mF + kF where 1F = 4;
		if (Seq == 6)
		{
			SeqArr[0] = 0;
			SeqArr[1] = 4;
			for (int i=2; i<=N; ++i)
			{
				SeqArr[i] = SeqArr[i-1] + SeqArr[1];
			}
			
		}
		
		// nF = (k+1)F*mF + (m-1)F*kF where 2F = 2
		if (Seq == 7)
		{
			SeqArr[0] = 0;
			SeqArr[1] = 1;
			SeqArr[2] = 2;
			for (int i=3; i<=N; ++i)
			{
				SeqArr[i] = SeqArr[2]*SeqArr[i-1] + SeqArr[i-2]*SeqArr[1];
			}
		}
		
		// nF = (k+1)F*mF + (m-1)F*kF where 2F = 3
		if (Seq == 8)
		{
			SeqArr[0] = 0;
			SeqArr[1] = 1;
			SeqArr[2] = 3;
			for (int i=3; i<=N; ++i)
			{
				SeqArr[i] = SeqArr[2]*SeqArr[i-1] + SeqArr[i-2]*SeqArr[1];
			}
		}
		
	}
	
	//-----------------------------------------------------------------
	void createCobweb( Graphics g)
	{
		int x, y, space_x;
		
		// create M levels
		Cobweb = new CVertex[M][];
					
		// Create vertices
		for (int iLevel=0; iLevel<M; ++iLevel)
		{
			Cobweb[iLevel] = new CVertex[SeqArr[iLevel + K + 1]];
			
			for (int iVert=0; iVert<SeqArr[iLevel + K + 1]; ++iVert)
			{
				
				g.setColor( Color.black );
				
				space_x = _SPACE_X ;//+ 2*SeqArr[iLevel];
				
				//x = _WIDTH/2 + iVert*_SPACE_X - _SPACE_X*(SeqArr[iLevel])/2 - K*_SPACE_X/2;
				
				x = _WIDTH/2 - space_x*SeqArr[iLevel+1 + K]/2 + space_x*iVert;
				
				y = _HEIGHT -  _SPACE_Y*(iLevel+K) - _SPACE_Y*(SeqArr[iLevel + K + 1])/3;
				
				Cobweb[iLevel][iVert] = new CVertex(x, y);

			}
			
		}
	}
	
	//-----------------------------------------------------------------
  	void drawCobweb (Graphics g)
  	{
	  	// Draw note
	  	Font ft = new Font ( "Tahoma", Font.BOLD, 12 );
		g.setFont (ft);
		
		switch (Seq)
		{
			case 1:
				g.drawString ("Natural numbers' Cobweb Poset", _WIDTH/2 - 90, 15 );
				break;
			
			case 2:
				g.drawString ("Fibonacci numbers' Cobweb Poset", _WIDTH/2 - 95, 15 );
				break;
				
			case 3:
				g.drawString ("Eeven natural numbers' Cobweb Poset", _WIDTH/2 - 115, 15 );
				break;
			
			default:
				g.drawString ("Cobweb Poset", _WIDTH/2 - 50, 15 );
				break;
						
		}
		
	  	
	  	
	  	// Draw vertices
		for (int iLevel=0; iLevel<M; ++iLevel)
		{
			for (int iVert=0; iVert<SeqArr[iLevel + K + 1]; ++iVert)
			{
				
				// draw chains				
				g.setColor( Color.blue );
				
				if (iLevel < M-1)
					for (int iTo=0; iTo<SeqArr[iLevel + K + 2]; ++iTo)
					{
						Cobweb[iLevel][iVert].draw_chain( g, Cobweb[iLevel+1][iTo] );
					}
					
				// draw vertex
				g.setColor( Color.black );
				
				Cobweb[iLevel][iVert].draw( g );
				
			}
			
			
			
				
		}
  	}
	
};

//---------------------------------------------------------------------
//---------------------------------------------------------------------
public class Cobweb extends Applet implements ItemListener
{
	Choice kL, nL, sequenceL;
	CobwebGraph tablet;
	
	int N = 7;
	int K = 0;
	int Seq = 1;
	
	
	//-----------------------------------------------------------------
	public void init()
	{        

		tablet = new CobwebGraph(K, N, Seq, getSize().width, getSize().height);
		
		kL = new Choice();
		nL = new Choice();
		sequenceL = new Choice();
		
		
		for (int i=0; i<=11; i++)
		{
			kL.addItem( new Integer(i).toString());
			nL.addItem( new Integer(i).toString());
		}
		
		kL.select(K);
		nL.select(N);
		
		setLayout( new BorderLayout() );
		
		Panel sPanel = new Panel();
		sPanel.setLayout( new FlowLayout() );
		
		// Labels 
		
		Label L1 = new Label("Sequence:");
		sPanel.add( L1 );
		L1.setBackground(Color.gray);
		
		sequenceL.addItem("1 - Natural numbers");
		sequenceL.addItem("2 - Fibonacci numbers");
		sequenceL.addItem("3 - Even Natural numbers");
		sequenceL.addItem("4 - nF = 2^n");
		sequenceL.addItem("5 - nF = mF + kF");
		sequenceL.addItem("6 - nF = mF + kF");
		sequenceL.addItem("7 - nF = (k+1)F*mF + (m-1)F*kF");
		sequenceL.addItem("8 - nF = (k+1)F*mF + (m-1)F*kF");
		
		
		sPanel.add( sequenceL );
		
		L1 = new Label("Layer");
		sPanel.add( L1 );
		L1.setBackground(Color.gray);
		
		L1 = new Label("K:");
		sPanel.add( L1 );
		L1.setBackground(Color.gray);
		
		sPanel.add( kL );
		
		L1 = new Label("N:");
		sPanel.add( L1 );
		L1.setBackground(Color.gray);
		
		sPanel.add( nL );
		
		
		
		add( "South", sPanel );
		add( "Center", tablet );
		

		tablet.setBackground(Color.white);
		sPanel.setBackground(Color.gray);
		
		
		kL.addItemListener( this );
		nL.addItemListener( this );
		sequenceL.addItemListener( this );
		
	}
	
	//-----------------------------------------------------------------
	public void itemStateChanged( ItemEvent evt )
	{        
		
		if ( evt.getSource() == kL ) {
			String s = evt.getItem().toString();
			K = Integer.parseInt( s );
		}
		
		if ( evt.getSource() == nL ) {
			String s = evt.getItem().toString();
			N = Integer.parseInt( s );
		}
		
		if ( evt.getSource() == sequenceL )
		{
			String s = evt.getItem().toString();
			Seq = Integer.parseInt(s.substring(0,1));
		}
			
		
		remove( tablet );
		tablet = new CobwebGraph(K, N, Seq, getSize().width, getSize().height);
		tablet.setBackground(Color.white);
		
		add( "Center", tablet );
		validate();
		

		
	}
};
