// A.Krzysztof Kwasniewski's Cobweb Poset
// Applet that draws partition of certain layer for
// the Natural numbers and the Fibonacci numbers
// author: Maciej Dziemianczuk
// www.faces-of-nature.art.pl/cobwebposet.html

import java.awt.*;
import java.awt.event.*;
import java.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)
	{
		g.fillOval(x-RADIUS/2, y-RADIUS/2, RADIUS, RADIUS);
	}
	
	// ----------------------------------------------
	public void draw_chain(Graphics g, CVertex to)
	{
		g.drawLine(x, y, to.x, to.y);
	}
}

// -----------------------------------------------------------------------------
class CCobwebAdmissibleSeq
{
	
	// ----------------------------------------------
	public CCobwebAdmissibleSeq() { }
	
	// ----------------------------------------------
	public int F(int _n) { return 0; }
	public int LambdaM(int _m, int _k) { return 0; }
	public int LambdaK(int _m, int _k) { return 0; }
	
	// ----------------------------------------------
	// get combination n after k
	public long comb(int n, int k)
	{
		
		if (k > n) return 0;
		if (n == k) return F(1);
		if (k + 1 == n) return F(n);
		
		// numerator & dominator
		long numerator = 1;
		long denominator = 1;
		for (int i=0; i<k; ++i)
		{
			numerator *= F(n-i);
			denominator *= F(k-i);
		}
		
		return numerator / denominator;
	}
	
}

// -----------------------------------------------------------------------------
class CSeqNatural extends CCobwebAdmissibleSeq
{
	// ----------------------------------------------
	public CSeqNatural() { }
	// ----------------------------------------------
	public int F(int _n)
	{
		return _n;
	}	
	// ----------------------------------------------
	public int LambdaM(int _m, int _k)
	{
		return 1;
	}
	// ----------------------------------------------
	public int LambdaK(int _m, int _k)
	{
		return 1;
	}
}

// -----------------------------------------------------------------------------
class CSeqFibonacci extends CCobwebAdmissibleSeq
{
	// ----------------------------------------------
	public CSeqFibonacci() { }
	// ----------------------------------------------
	public int F(int _n)
	{
		if (_n < 1) return 0;
		if (_n == 1 || _n == 2) return 1;
		return F(_n-1) + F(_n-2);
	}
	// ----------------------------------------------
	public int LambdaM(int _m, int _k)
	{
		return F(_k+1);
	}
	// ----------------------------------------------
	public int LambdaK(int _m, int _k)
	{
		return F(_m-1);
	}
}

// -----------------------------------------------------------------------------
class CSeqGauss extends CCobwebAdmissibleSeq
{
	private int _q = 2;
	
	// ----------------------------------------------
	public CSeqGauss() { }
	// ----------------------------------------------
	public int F(int _n)
	{
		if (_n < 1) return 0;
    	if (_n == 1) return 1;
		
    	return F(1) * ((int)Math.pow(_q, _n) - 1)/(_q - 1);
    
	}
	// ----------------------------------------------
	public int LambdaM(int _m, int _k)
	{
		return (int)Math.pow(_q, _k);
	}
	// ----------------------------------------------
	public int LambdaK(int _m, int _k)
	{
		return 1;
	}
}

// -----------------------------------------------------------------------------
// Calculate partition i.e. set of blocks
//
// -----------------------------------------------------------------------------
class CGetPartition
{
	
	private long NumberOfBlocks;
	private int N;
	private int K;
	private int M;
	
	// Sequence
	private CCobwebAdmissibleSeq Seq;
	
	// [x][][] - block
	// [][x][] - block's level 
	// [][][x] - level's element
	
	public int Partition[][][];
	
	// ----------------------------------------------
	public CGetPartition(int _n, int _k, CCobwebAdmissibleSeq _seq)
	{
		Seq = _seq;

		N = _n;
		K = _k;
		M = N - K + 1;
		
		NumberOfBlocks = Seq.comb(N, K-1);
	}
	
	// ----------------------------------------------
	// create Partition
	public int[][][] get()
	{
		// - - - Init Partition
		
		// Partition has C(n, k) blocks
		Partition = new int [(int)NumberOfBlocks][][];
		System.out.println("Number of blocks = " + (int)NumberOfBlocks + " K " + K + " N " + N);
		for (int iB=0; iB < NumberOfBlocks; ++iB) 
		{
			// each of blocks has M levels
			Partition[iB] = new int [M][];
			
			// each of levels has nF elements 
			//(not exactly but it'll be more easy)
			for (int iL=0; iL < M; ++iL)
			{
				Partition[iB][iL] = new int[Seq.F(N)];
				// clear all of elements
				for (int iE=0; iE < Seq.F(N); ++iE)
					Partition[iB][iL][iE] = 0;
			}
			
		}
		
		// fill out first block
		for (int iL=0; iL < M; ++iL)
		{
			for (int iE=0; iE < Seq.F(K+iL); ++iE)
			{
				Partition[0][iL][iE] = iE + 1;
			}
		}
		
		// main function to get formula
		solve(N, K, 0);
		
		return Partition;
	}
	
	
	// ----------------------------------------------
	public void solve(int _n, int _k, int _first)
	{
		//System.out.println("solve " + _n + ", " + _k + ", " + _first + ".");
		//if (++Count >= 3) return;
		
		// Rules of non-terminal symbols
		// I. |phi_1| = 1F
		int count = 0;
		int tmp, iB, iL, iE, iM;
		
		
		for (iE=0; iE < Seq.F(N); ++iE)
		{
			if (Partition[_first][_n-_k][iE] > 0) ++count;
		}
		if (count == Seq.F(_n - _k + 1))
		{
			// we do nothing
			//System.out.println("Rule I.");
			//print();
			return;
		}
		
		// II. m == 1
		int m = _n - _k + 1;
		if (m == 1)
		{
			// we have to separate this level to 1F vertices
			count = 0;
			for (iE=0; iE < Seq.F(N); ++iE)
			{
				if (Partition[_first][0][iE] > 0) ++count;
			}
			
			//System.out.println("count =" + count + " /=" + (count/F(1)));
			//System.out.println(">>> " + Partition[3][0][1]);
			
			// on count/1F blocks
			for (iB=1; iB < (count/Seq.F(1)); ++iB)
			{
				for (iE=0; iE < Seq.F(1); ++iE)
				{
					//System.out.println("Partition[" + (_first + iB)  + "][0][" + iE + "] = ");
					//System.out.println(" = partition[" +_first+ "][0][" + (iB*(int)F(1) + iE) +"] =" + Partition[_first][0][iB*(int)F(1) + iE]);
					
					Partition[_first + iB][0][iE] = Partition[_first][0][iB*(int)Seq.F(1) + iE];
					Partition[_first][0][iB*(int)Seq.F(1) + iE] = 0;
				}
			}
			//System.out.println("Rule II.");
			//print();
			
			return;
		}
		
		
		// III. Recurrence u --> u'v + sigma(u")
		// separate to two disjoin situation A, B
		int NumA = (int)Seq.comb(_n-1, _k-1);
		int MultA = Seq.LambdaM(m, _k-1);
		
		
		
		int MultB = Seq.LambdaK(m, _k);
		int NumB = (int)(Seq.comb(_n, _k - 1) - NumA*MultA)/MultB;
		
		
		//System.out.println("NumA = " + NumA + " NumB=" + NumB + " MultA =" + MultA + " MultB=" + MultB);
		
		// create copy of first block
		int Block[][] = new int [M][(int)Seq.F(N)];
		for (iL=0; iL < M; ++iL)
			for (iE=0; iE < Seq.F(N); ++iE)
			{
				if (Partition[_first][iL][iE] > 0)
					Block[iL][iE] = Partition[_first][iL][iE];
				else
					Block[iL][iE] = 0;
				
				//Partition[_first][iL][iE] = 0;
			}
		
		// copy this block to MultA blocks 
		for (iB=1; iB < MultA; ++iB)
		{
			for (iL=0; iL < M; ++iL)
				for (iE=0; iE < Seq.F(N); ++iE)
				{
					Partition[_first + iB*NumA][iL][iE] = Block[iL][iE];
				}
		}
		
		
		// change A part
		// 1. change last (m-1) level of first NumA blocks
		//    - set first mF vertices, last ones remove
		for (iM=0; iM < MultA; ++iM)
		{
			for (iB=(_first+iM*NumA); iB < (_first+iM*NumA + NumA); ++iB)
			{
				for (iE=0; iE < Seq.F(N); ++iE)
				{
					if (iE < Seq.F(m))
					{
						//System.out.println("[] " + iB + " [] " + (m-1) + " [] " + iE);
						
						Partition[iB][m - 1][iE] = Block[m - 1][iM*Seq.F(m) + iE];
					}
					else
						Partition[iB][m - 1][iE] = 0;
				}
			}
		}
		
		// change B part
		// 2. set on first of rest blocks 
		for (iM=0; iM < MultB; ++iM)
		{
			// first level from last level
			// at first clear, next fill out
			for (iE=0; iE < Seq.F(N); ++iE)
				Partition[_first + (NumA*MultA + iM*NumB)][0][iE] = 0;				
			for (iE=0; iE < Seq.F(_k-1); ++iE)
				Partition[_first + (NumA*MultA + iM*NumB)][0][iE] = Block[m - 1][MultA*(int)Seq.F(m) + iM*(int)Seq.F(_k-1) + iE];
			
			
			for (iL=1; iL < m; ++iL)
			{
				for (iE=0; iE < Seq.F(N); ++iE)
				{
					Partition[_first + (NumA*MultA + iM*NumB)][iL][iE] = Block[iL - 1][iE];
				}
			}
		}
		
		//System.out.println("Rule III.");
		//print();
		
		// Reccurence of A
		
		for (iM=0; iM < MultA; ++iM)
		{
			//System.out.println(iM + ". - solve(" + (_n - 1) + ", " + (_k) +", " + ( _first + iM*NumA) + ")");
			solve(_n - 1, _k, _first + iM*NumA);
		}
		// Reccurence of B
		for (iM=0; iM < MultB; ++iM)
		{
			//System.out.println(iM + ". + solve("+(_n - 1)+","+(_k - 1)+","+(_first + NumA*MultA + iM*MultB)+")");
			solve(_n - 1, _k - 1, _first + NumA*MultA + iM*NumB);
		}
		
		
		//System.out.println("Before changing order of levels m=" + m + " NumB=" + NumB + " NumA=" + NumA);
		//print();
		
		// Change order of NumB blocks
		for (iM=0; iM < MultB; ++iM)
		{
			for (iB=0; iB < NumB; ++iB)
			{
				// backup them at first
				// create copy of first block
				Block = new int [m][(int)Seq.F(N)];
				for (iL=0; iL < m; ++iL)
					for (iE=0; iE < Seq.F(N); ++iE)
					{
						Block[iL][iE] = Partition[_first + NumA*MultA + iM*NumB + iB][iL][iE];
					}
				
				// change order from copy
				for (iL =0; iL < m; ++iL)
					for (iE=0; iE < Seq.F(N); ++iE)
					{
						Partition[_first + NumA*MultA + iM*NumB + iB][iL][iE] = Block[(iL + 1)%m][iE];
					}
			}
		}
		
		//System.out.println("After changing order of levels");
		//print();
		
	}
	
	
	
	
	// ----------------------------------------------
	// print partition
	public void print()
	{
		System.out.println("Partition:");
		for (int iB=0; iB < NumberOfBlocks; ++iB)
		{
			System.out.print(iB+1 + ". ");
			for (int iL=0; iL < M; ++iL)
			{
				System.out.print("{");
				for (int iE=0; iE < Seq.F(N); ++iE)
				{
					if (Partition[iB][iL][iE] > 0)
						//System.out.print(iE + "=");
						System.out.print(Partition[iB][iL][iE] + ",");
				}
				System.out.print("}");
			}
			System.out.println(" ");
		}
	}
	
}

// -----------------------------------------------------------------------------
// Draw everything with selected block
//
// -----------------------------------------------------------------------------
class CTileGraphics extends Applet
{
	// Private members
	private int N;		// Last level
	private int K;		// First level
	private int M;
	private CCobwebAdmissibleSeq Seq;	// Sequence
		
	private float SCALE = 1.0f;
	private int WIDTH;
	private int HEIGHT;
	private int OX = 30; 
	private int OY = 30;
	private Graphics g;
	
	// Colors
	Color cChain 		= new Color(210, 210, 210);
	Color cVertex 		= Color.black;
	Color cBlockChain 	= new Color(128, 0, 0);
	Color cBlockVertex 	= Color.red;
	
	// Hasse diagram
	// [x][] - level
	// [][x] - vertex
	private CVertex CobwebPoset[][];
	// Block of Partition
	private int Block[][];
	
	// ----------------------------------------------
	public CTileGraphics(int _n, int _k, CCobwebAdmissibleSeq _seq, int _block[][])
	{
		N = _n;
		K = _k;
		M = N - K + 1;
		
		Seq = _seq;
		
		CobwebPoset = new CVertex[M][];
		Block = _block;
	}
	
	// ----------------------------------------------
	public void paint(Graphics _g)
	{
		WIDTH = getSize().width - 50;
		HEIGHT = getSize().height - 50;
		OY = getSize().height - 30;
		
		g = _g;
		Rectangle r = getBounds();
		g.setColor( Color.black );
		
		// 1. Draw arrangement
		draw_arrangement();
		
		// 2. Draw Hasse diagram
		draw_hasse();
		
		// 3. Draw selected block (in color)
		draw_block();
	}
	
	// ----------------------------------------------
	public void draw_block()
	{
		int iL, iV, iV2;
		if (Block == null) return;
		
		// draw chains of block
		g.setColor(cBlockChain);
		for (iL=0; iL < M-1; ++iL)
		{
			for (iV=0; iV < Seq.F(N); ++iV)
			{
				if (Block[iL][iV] > 0)
					for (iV2=0; iV2 < Seq.F(N); ++iV2)
					{
						if (Block[iL+1][iV2] > 0)
							CobwebPoset[iL][Block[iL][iV]-1].draw_chain(g, CobwebPoset[iL+1][Block[iL+1][iV2]-1]);
					}
			}
		}
		
		// draw block
		g.setColor(cBlockVertex);
		for (iL=0; iL < M; ++iL)
		{
			for (iV=0; iV < Seq.F(N); ++iV)
			{
				if (Block[iL][iV] > 0)
					CobwebPoset[iL][Block[iL][iV]-1].draw(g);
					
			}
		}
	}
	
	// ----------------------------------------------
	public void draw_hasse()
	{
		float DLevel = (float)HEIGHT / (float)(M-1);
		float DVertex = (float)(WIDTH-10) / (float)(Seq.F(N)-1);
		int iLevel, iL, iV, iV2, iVertex;
		
		// draw levels
		for (iL=0; iL < M; ++iL)
		{
			iLevel = OY - (int)(DLevel * iL);
			// level
			g.setColor(new Color(220,220,220));
			g.drawLine(OX, iLevel, OX+WIDTH, iLevel);
			
			// notation of level
			g.setColor(Color.black);
			g.setFont(new Font ( "Sans", Font.PLAIN, 10 ));
			g.drawString(new Integer(iL + K).toString(), OX - 14, iLevel + 7);
			// symbol PHI
			g.drawOval(OX - 24, iLevel - 3, 8, 6);
			g.drawLine(OX - 20, iLevel - 5, OX - 20, iLevel + 5);
			g.drawLine(OX - 22, iLevel - 5, OX - 18, iLevel - 5);
			g.drawLine(OX - 22, iLevel + 5, OX - 18, iLevel + 5);
			
			// create Vertices
			CobwebPoset[iL] = new CVertex[Seq.F(K+iL)];
			for (iV=0; iV < Seq.F(K+iL); ++iV)
			{
				iVertex = OX + (int)(iV * DVertex) + 10;
				CobwebPoset[iL][iV] = new CVertex(iVertex, iLevel);
				//g.fillOval(iVertex, iLevel-5, 10, 10);
			}
		}
		
		// draw chains
		g.setColor(cChain);
		for (iL=0; iL < M-1; ++iL)
		{
			for (iV=0; iV < Seq.F(K+iL); ++iV)
			{
				// get vertex with vertex in next level
				for (iV2=0; iV2 < Seq.F(K+iL+1); ++iV2)
				{
					
					CobwebPoset[iL][iV].draw_chain(g, CobwebPoset[iL+1][iV2]);
				}
			}
		}
		
		// draw Vertices
		g.setColor(cVertex);
		for (iL=0; iL < M; ++iL)
		{
			for (iV=0; iV < Seq.F(K+iL); ++iV)
			{
				CobwebPoset[iL][iV].draw(g);
			}
		}
	}
	
	// ----------------------------------------------
	public void draw_arrangement()
	{	
		// Y axis
		g.drawLine(OX-1, OY+5, OX-1 , OY - HEIGHT-5);
		
		g.setColor(new Color(220,220,220));
		// X axis
		//g.drawLine(OX, OY, OX + WIDTH, OY);
	}
}

// -----------------------------------------------------------------------------
// Info:
// We calculate partition only when we change Numbers or size of layers, so
// Partition is global variable
// -----------------------------------------------------------------------------
public class TileMethod extends Applet implements ActionListener 
{
	// GUI members
	private Button bDraw, bPrev, bNext;
	private TextField tfK, tfN, tfCol;
	private Choice lSeq;
	Panel nPanel, paneMain, pGraph;
	private Label lab;
	
	// Default values
	private int K = 3;
	private int N = 5;
	private int Numbers = 1;
	private int Cols = 2; // number of columns to show diagrams
	private CCobwebAdmissibleSeq Seq;
	private int blockActual = 1;
	private int blockAll;
	
	
	// color of panel
	Color bg = new Color(180,180,180);
	Color bgN = new Color(200,200,200);
	
	// Tablet
	private CTileGraphics Tablet;
	private CTileGraphics Tablets[];
	
	// partition
	private int Partition[][][];
	
	// ----------------------------------------------
	public void init() {
		
		//CGetTile Tile = new CGetTile(6, 4, 1);
		//setBackground(new Color(0,150,0));
		
		// - - - GUI 
		setLayout( new BorderLayout() );
		
		add("North", paneTitle());
		add("South", paneOptSouth());
		
		// update N, K, other vars (1 - all)
		update(1);
		
		// -- -- -- -- -- -- -- -- -- -- -- -- -
		// -- Main graphics class - center panel
		//Tablet = new CTileGraphics(N, K, Seq, Partition[blockActual-1]);
		//Tablet.setBackground(Color.white);
		
		pGraph = new Panel(new GridLayout(Cols,2));
		
		Tablets = new CTileGraphics [(int)Seq.comb(N,N-K+1)];
		System.out.println("created " + ((int)Seq.comb(N,K)));
		
		for (int i=0; i<(int)Seq.comb(N,N-K+1); ++i)
		{
			Tablets[i] = new CTileGraphics(N, K, Seq, Partition[i]);
			pGraph.add(Tablets[i]);
		}
		
		paneMain = new Panel();
		paneMain.setLayout(new BorderLayout());
		paneMain.setBackground(Color.white);
		paneMain.add("Center", pGraph);
		paneMain.add("South", paneOptNorth());
		
		add("Center", paneMain);
	}
	
	// ----------------------------------------------
	// 1 - all
	// 2 - without partition
	public void update(int _mode)
	{
		K = Integer.parseInt( tfK.getText() );
		N = Integer.parseInt( tfN.getText() );
		Numbers = lSeq.getSelectedIndex();
		Cols = Integer.parseInt( tfCol.getText() );
		
		// Create cobweb admissible sequence
		switch (Numbers)
		{
			default:
				Seq = new CSeqNatural();
				break;
				
			case 1:
				Seq = new CSeqFibonacci();
				break;
				
			case 2:
				Seq = new CSeqGauss();
				break;
		}
				
		blockAll = (int)Seq.comb(N, K-1);
		
		if (_mode == 1)
		{
			blockActual = 1;
			// Create and calculate new partition
			CGetPartition part = new CGetPartition(N, K, Seq);
			Partition = part.get();
		}
		
	}
	
	// ----------------------------------------------
	// print partition
	public void print()
	{
		System.out.println("Partition:");
		for (int iB=0; iB < blockAll; ++iB)
		{
			System.out.print(iB+1 + ". ");
			for (int iL=0; iL < (N - K + 1); ++iL)
			{
				System.out.print("{");
				for (int iE=0; iE < Seq.F(N); ++iE)
				{
					if (Partition[iB][iL][iE] > 0)
						//System.out.print(iE + "=");
						System.out.print(Partition[iB][iL][iE] + ",");
				}
				System.out.print("}");
			}
			System.out.println(" ");
		}
	}
	
	
	// ----------------------------------------------
	public void actionPerformed( ActionEvent evt )
	{
		if (evt.getSource() == bPrev )
		{
			if (K <= 1)
				K = N;
			else
				K --;
			tfK.setText(Integer.toString(K));
		}
		if (evt.getSource() == bNext )
		{
			if (K >= N)
				K = 1;
			else
				K ++;
				
			tfK.setText(Integer.toString(K));
		} 
		
		//if (evt.getSource() == bDraw )
		//{
		//	mode = 1;
		//}
		
		int mode = 1;
		
		
		remove ( pGraph );
		//remove ( Tablet );
		remove( paneMain );
		
		update(mode);
		
		pGraph = new Panel(new GridLayout(Cols,2));
		
		//Tablet = new CTileGraphics(N, K, Seq, Partition[blockActual-1]);
		//Tablet.setBackground(Color.white);
		
		Tablets = new CTileGraphics [(int)Seq.comb(N,N-K+1)];
		for (int i=0; i<(int)Seq.comb(N,N-K+1); ++i)
		{
			Tablets[i] = new CTileGraphics(N, K, Seq, Partition[i]);
			Tablets[i].setBackground(Color.white);
			
			pGraph.add(Tablets[i]);
		}
		
		paneMain = new Panel();
		paneMain.setLayout(new BorderLayout());
		paneMain.setBackground(Color.white);
		paneMain.add("Center", pGraph);
		paneMain.add("South", paneOptNorth());
	
		add( "Center", paneMain);
		validate();
		
		
	}

	// ----------------------------------------------
	private Panel paneTitle()
	{
		// - - - Panel Title
		Panel pTitle = new Panel();	
		pTitle.setBackground(Color.gray);
		
		Label title = new Label("Cobweb posets tiling process");
		Font ft = new Font ( "Tahoma", Font.BOLD, 12 );
		
		title.setFont(ft);
		title.setBackground(Color.gray);
		title.setForeground(Color.white);
		pTitle.add(title);
		
		return pTitle;
	}
	
	// ----------------------------------------------
	private Panel paneOptNorth()
	{
		// - - - Panel Options North
		Panel nPanel = new Panel();
		nPanel.setBackground(bgN);
		nPanel.setLayout(new BorderLayout(0,0));
		
		Panel pCenter = new Panel();
		pCenter.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
		
		lab = new Label("Blocks: " + new Integer(blockAll).toString());
		lab.setFont(new Font("Dialog", Font.PLAIN, 11));
		pCenter.add(lab);
		
		// Control buttons
		Font ft = new Font( "Dialog", Font.PLAIN, 10 );
		
		
		bPrev = new Button("<<< PREV k ");
		bPrev.setFont(ft);
		bPrev.addActionListener(this);
		
		bNext = new Button(" NEXT k >>>");
		bNext.setFont(ft);
		bNext.addActionListener(this);
		
		nPanel.add("West", bPrev);
		nPanel.add("Center", pCenter);
		nPanel.add("East", bNext);
		
		return nPanel;
	}
	
	// ----------------------------------------------
	private Panel paneOptSouth()
	{
		// - - - Panel Options South
		Panel sPanel = new Panel();
		sPanel.setBackground(bg);
		lab = new Label("Sequence:");
		lab.setBackground(bg);
		sPanel.add(lab);
		
		lSeq = new Choice();
		lSeq.addItem("1 Natural numbers");
		lSeq.addItem("2 Fibonacci numbers");
		lSeq.addItem("3 Gaussian numbers");
		sPanel.add(lSeq);
		
		lab = new Label("Layer k:");
		lab.setBackground(bg);
		sPanel.add(lab);
		
		tfK = new TextField(new Integer(K).toString(),2);
		sPanel.add(tfK);
		
		lab = new Label("n:");
		lab.setBackground(bg);
		sPanel.add(lab);
		
		tfN = new TextField(new Integer(N).toString(),2);
		sPanel.add(tfN);
		
		lab = new Label("Cols:");
		lab.setBackground(bg);
		sPanel.add(lab);
		
		tfCol = new TextField(new Integer(Cols).toString(),2);
		sPanel.add (tfCol);
		
		bDraw = new Button(" C R E A T E ");
		Font ft = new Font( "Serif", Font.BOLD, 10 );
		bDraw.setFont(ft);
		bDraw.addActionListener(this);
		sPanel.add(bDraw);
		
		return sPanel;
	}
	

}

