// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) fieldsfirst 
// Source File Name:   worker.java

package lt.ktu.gmj.analysis;

import java.awt.Rectangle;
import java.util.Random;
import java.util.Vector;
import javax.swing.JLabel;
import javax.swing.Timer;

// Referenced classes of package lt.ktu.gmj.analysis:
//			Plokste, cutAnalyser, DrawingPanel

class worker extends Thread
{

	Vector m_pPatterns;
	Vector m_pPatternsOrig;
	Vector m_pPatternsBest;
	cutAnalyser ct;
	int m_iLeft;
	int m_iTop;
	int m_iBottom;
	int m_iRight;
	int m_iRandom;
	int m_iBigest;
	int m_iSmallest;
	private static Random randomizer = null;

	public worker(cutAnalyser cutanalyser, int i, int j, int k, int l, Vector vector, int i1, 
			int j1, int k1)
	{
		m_pPatterns = new Vector();
		m_pPatternsOrig = new Vector();
		m_pPatternsBest = new Vector();
		ct = cutanalyser;
		m_iLeft = i;
		m_iTop = j;
		m_iBottom = k;
		m_iRight = l;
		m_iRandom = i1;
		m_iBigest = j1;
		m_iSmallest = k1;
		copyVector(vector, m_pPatterns);
		copyVector(vector, m_pPatternsOrig);
		setPriority(1);
	}

	public void run()
	{
		boolean flag = true;
		while(ct.timer.isRunning()) 
		{
			putFirst();
			if(putThemAll())
			{
				flag = false;
				ct.timer.stop();
			}
			nullVector(m_pPatterns);
			mixVector(m_pPatterns);
			try
			{
				Thread.sleep(2L);
			}
			catch(InterruptedException interruptedexception) { }
		}
		if(flag)
			ct.lblStatus.setText("Done. Filled area is " + calculateArea(m_pPatternsBest) + " units.");
		ct.pnlMain.setValues(m_iLeft, m_iTop, m_iBottom, m_iRight, m_pPatternsBest);
		ct.pnlMain.repaint();
	}

	private boolean putFirst()
	{
		Object obj = null;
		for(int i = 0; i < m_pPatterns.size(); i++)
		{
			Plokste plokste = (Plokste)m_pPatterns.elementAt(i);
			if(!plokste.m_bUsed)
			{
				if(m_iRight - m_iLeft >= plokste.nWidth && m_iBottom - m_iTop >= plokste.nHeight)
				{
					plokste.setPlokste(m_iLeft, m_iTop, plokste.nWidth, plokste.nHeight, true);
					return true;
				}
				if(m_iRight - m_iLeft >= plokste.nHeight && m_iBottom - m_iTop >= plokste.nWidth)
				{
					plokste.setPlokste(m_iLeft, m_iTop, plokste.nHeight, plokste.nWidth, true);
					return true;
				}
			}
		}

		return false;
	}

	private boolean putThemAll()
	{
		Object obj = null;
		Object obj1 = null;
		int j = 0;
		int k = 0;
		do
		{
			for(int l = 0; l < m_pPatterns.size(); l++)
			{
				int i = -1;
				Plokste plokste = (Plokste)m_pPatterns.elementAt(l);
				if(plokste.m_bUsed && (i = findFreeBorder(plokste)) > 2)
				{
					for(int i1 = 0; i1 < m_pPatterns.size(); i1++)
					{
						Plokste plokste1 = (Plokste)m_pPatterns.elementAt(i1);
						if(!plokste1.m_bUsed && joinTogether(plokste, plokste1, i))
							break;
					}

				}
			}

			if(calculateArea(m_pPatterns) >= calculateArea(m_pPatternsBest))
				copyVector(m_pPatterns, m_pPatternsBest);
			if(calculateArea(m_pPatterns) == m_iRight * m_iBottom)
			{
				ct.lblStatus.setText("All area was filled.");
				return true;
			}
			if(m_pPatterns.size() == calculateUsed(m_pPatterns))
			{
				ct.lblStatus.setText("All patterns were used.");
				return true;
			}
			if(j == calculateUsed(m_pPatterns))
			{
				k++;
			} else
			{
				k = 0;
				j = calculateUsed(m_pPatterns);
			}
		} while(k != 4);
		return false;
	}

	private int findFreeBorder(Plokste plokste)
	{
		boolean flag = true;
		boolean flag1 = true;
		Object obj = null;
		if(plokste.nLeft + plokste.nWidth == m_iRight)
			flag = false;
		if(plokste.nTop + plokste.nHeight == m_iBottom)
			flag1 = false;
		for(int i = 0; i < m_pPatterns.size(); i++)
		{
			Plokste plokste1 = (Plokste)m_pPatterns.elementAt(i);
			if(plokste1.m_bUsed && plokste.ID != plokste1.ID)
			{
				if(plokste.nLeft + plokste.nWidth == plokste1.nLeft && plokste.nTop >= plokste1.nTop && plokste.nTop <= plokste1.nBottom)
					flag = false;
				if(plokste.nTop + plokste.nHeight == plokste1.nTop && plokste.nLeft >= plokste1.nLeft && plokste.nLeft <= plokste1.nRight)
					flag1 = false;
			}
		}

		if(flag)
			return 3;
		else
			return flag1 ? 4 : 0;
	}

	private boolean isPointOutside(int i, int j)
	{
		return i < m_iLeft || i > m_iRight || j < m_iTop || j > m_iBottom;
	}

	private boolean checkIntersection(Plokste plokste)
	{
		Object obj = null;
		if(!isPointOutside(plokste.nLeft, plokste.nTop) && !isPointOutside(plokste.nRight, plokste.nTop) && !isPointOutside(plokste.nRight, plokste.nBottom) && !isPointOutside(plokste.nLeft, plokste.nBottom))
		{
			for(int i = 0; i < m_pPatterns.size(); i++)
			{
				Plokste plokste1 = (Plokste)m_pPatterns.elementAt(i);
				if(plokste1.m_bUsed && plokste1.ID != plokste.ID)
				{
					Rectangle rectangle = new Rectangle(plokste1.nLeft, plokste1.nTop, plokste1.nWidth, plokste1.nHeight);
					Rectangle rectangle1 = new Rectangle(plokste.nLeft, plokste.nTop, plokste.nWidth, plokste.nHeight);
					boolean flag = rectangle.intersects(rectangle1);
					if(flag)
						return flag;
				}
			}

		} else
		{
			return true;
		}
		return false;
	}

	private boolean joinTogether(Plokste plokste, Plokste plokste1, int i)
	{
		Plokste plokste2 = new Plokste(plokste1.nLeft, plokste1.nTop, plokste1.nWidth, plokste1.nHeight, plokste1.ID, false);
		if(i == 3)
		{
			plokste1.setPlokste(plokste.nRight, plokste.nTop, plokste1.nWidth, plokste1.nHeight, false);
			if(!checkIntersection(plokste1))
			{
				plokste1.m_bUsed = true;
				return true;
			}
			plokste1.setPlokste(plokste.nLeft + plokste.nWidth, plokste.nTop, plokste1.nHeight, plokste1.nWidth, false);
			if(!checkIntersection(plokste1))
			{
				plokste1.m_bUsed = true;
				return true;
			}
		} else
		if(i == 4)
		{
			plokste1.setPlokste(plokste.nLeft, plokste.nBottom, plokste1.nWidth, plokste1.nHeight, false);
			if(!checkIntersection(plokste1))
			{
				plokste1.m_bUsed = true;
				return true;
			}
			plokste1.setPlokste(plokste.nLeft, plokste.nBottom, plokste1.nHeight, plokste1.nWidth, false);
			if(!checkIntersection(plokste1))
			{
				plokste1.m_bUsed = true;
				return true;
			}
		}
		plokste1.setPlokste(plokste2.nLeft, plokste2.nTop, plokste2.nWidth, plokste2.nHeight, false);
		return false;
	}

	private void copyVector(Vector vector, Vector vector1)
	{
		vector1.removeAllElements();
		for(int i = 0; i < vector.size(); i++)
		{
			Plokste plokste = (Plokste)vector.elementAt(i);
			vector1.addElement(new Plokste(plokste.nLeft, plokste.nTop, plokste.nWidth, plokste.nHeight, plokste.ID, plokste.m_bUsed));
		}

	}

	private void nullVector(Vector vector)
	{
		for(int i = 0; i < vector.size(); i++)
		{
			Plokste plokste = (Plokste)vector.elementAt(i);
			plokste.setPlokste(0, 0, plokste.nWidth, plokste.nHeight, false);
		}

	}

	private void mixVector(Vector vector)
	{
		boolean flag = false;
		if(randomizer == null)
			randomizer = new Random();
		int i = randomizer.nextInt(100);
		if(i >= 0 && i < m_iRandom)
			mixRandom(vector);
		else
		if(i >= m_iRandom && i < m_iRandom + m_iBigest)
			mixMax(vector);
		else
			mixMin(vector);
	}

	private void mixRandom(Vector vector)
	{
		int i = 0;
		if(randomizer == null)
			randomizer = new Random();
		while(i < vector.size()) 
		{
			for(int j = 0; j < vector.size() - 1; j++)
			{
				Plokste plokste = (Plokste)vector.elementAt(j);
				if(randomizer.nextBoolean())
				{
					vector.setElementAt(vector.elementAt(vector.size() - 1 - j), j);
					vector.setElementAt(plokste, vector.size() - 1 - j);
				} else
				{
					vector.setElementAt(vector.elementAt(j + 1), j);
					vector.setElementAt(plokste, j + 1);
					i++;
				}
			}

		}
	}

	private void mixMax(Vector vector)
	{
		boolean flag = false;
		for(int k = 0; k < vector.size(); k++)
		{
			boolean flag1 = false;
			Plokste plokste = (Plokste)vector.elementAt(k);
			int i = k;
			int j = plokste.getArea();
			for(int l = k + 1; l < vector.size(); l++)
			{
				Plokste plokste1 = (Plokste)vector.elementAt(l);
				if(j < plokste1.getArea())
				{
					i = l;
					j = plokste1.getArea();
					flag1 = true;
				}
			}

			if(flag1)
			{
				vector.setElementAt(vector.elementAt(i), k);
				vector.setElementAt(plokste, i);
				return;
			}
		}

	}

	private void mixMin(Vector vector)
	{
		boolean flag = false;
		for(int k = 0; k < vector.size(); k++)
		{
			boolean flag1 = false;
			Plokste plokste = (Plokste)vector.elementAt(k);
			int i = k;
			int j = plokste.getArea();
			for(int l = k + 1; l < vector.size(); l++)
			{
				Plokste plokste1 = (Plokste)vector.elementAt(l);
				if(j > plokste1.getArea())
				{
					i = l;
					j = plokste1.getArea();
					flag1 = true;
				}
			}

			if(flag1)
			{
				vector.setElementAt(vector.elementAt(i), k);
				vector.setElementAt(plokste, i);
				return;
			}
		}

	}

	private int calculateArea(Vector vector)
	{
		int i = 0;
		Object obj = null;
		for(int j = 0; j < vector.size(); j++)
		{
			Plokste plokste = (Plokste)vector.elementAt(j);
			if(plokste.m_bUsed)
				i += plokste.getArea();
		}

		return i;
	}

	private int calculateUsed(Vector vector)
	{
		int i = 0;
		Object obj = null;
		for(int j = 0; j < vector.size(); j++)
		{
			Plokste plokste = (Plokste)vector.elementAt(j);
			if(plokste.m_bUsed)
				i++;
		}

		return i;
	}

}
