package net.sourceforge.phpeclipse.phpunit;

import java.io.IOException;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

/**
 * @author Ali Echihabi
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
/*
 * Created on May 22, 2004
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */

/**
 * @author Ali Echihabi (ali_echihabi@ieee.org)
 *
 * Plugin for PHP unit Testing.
 * www.phpeclipse.de
 * 
 * This the main view showing the progress and reports.
 * 
 */

public class PHPUnitView extends ViewPart {

	/*
	 * like J Unit
	 * a tree.
	 * The first level nodes are the test suites.
	 * children are nested test suites.
	 * leafs: test functions.
	 * hierarchy: package->testsuite1->testcase->test_function
	 */

	private int numTests; // total number of tests
	private int numTestsRun; // number of tests run so far
	private int numFailures; // number of failures so far
	private int numErrors; // number of errors so far
	private int numPasses; // number of passes so far (they should add up)	 

	private XMLReportHandler handler;



	private TestPool testPool;

	private Button startButton;

	private ProgressInfoComposite progressInfoComposite;
	private ResultsInfoComposite resultsInfoComposite;
	private Group settingsInfoComposite; //TODO: move somewhere else, launcher, wizard or preferences.
	


	public PHPUnitView() {
		handler = new XMLReportHandler();
		testPool = new TestPool();
		

	}

	public void createPartControl(Composite parent) {

		parent.setLayout(new FillLayout(SWT.VERTICAL));

		//Launch ToolBar:
		setActions();

		//Build the progress info Composite		s		
		progressInfoComposite = new ProgressInfoComposite(parent);
		

		//Build the result info composite
		resultsInfoComposite = new ResultsInfoComposite(parent);
		
		//build the settings composite
		buildSettingsComposite(parent);

		startButton = new Button(parent, SWT.CENTER);
		startButton.setText("Start Tests");
		startButton.addMouseListener(new MouseListener() {

			public void mouseDoubleClick(MouseEvent arg0) {

			}

			public void mouseDown(MouseEvent arg0) {

				startTests();

			}

			public void mouseUp(MouseEvent arg0) {

			}

		}); // end add action listener.

	}

	/**
	 * @param parent
	 */
	private void buildSettingsComposite(Composite parent) {
		
		
		settingsInfoComposite = new Group(parent, SWT.NONE);
//		settingsInfoComposite.setText("Settings");
//		settingsInfoComposite.setLayout(new GridLayout(2,false));
//		
//		
//		//the test suite to launch
//		Label testSuiteLabel = new Label(settingsInfoComposite, SWT.NONE);
//		testSuiteLabel.setText("Test suite to run:");
//		//testSuiteLabel.setLayoutData(new GridData())
//		Text testSuiteText = new Text(settingsInfoComposite, SWT.NONE);
//		
//		//the path to php
//		Label phpPathLabel = new Label(settingsInfoComposite, SWT.NONE);
//		phpPathLabel.setText("php Path:");
//		//testSuiteLabel.setLayoutData(new GridData())
//		Text phpPathText = new Text(settingsInfoComposite, SWT.NONE);
		

		
	}

	private void setActions() {
		final IActionBars actionBars = getViewSite().getActionBars();
		IToolBarManager toolBarManager = actionBars.getToolBarManager();
		Action action1 = new Action() {};
		action1.setText("Action 1");
		action1.setToolTipText("Start the testing");
		//final URL installUrl = PaintPlugin.getDefault().getDescriptor().getInstallURL();
		//final URL imageUrl = new URL(installUrl, PaintPlugin.getResourceString(id + ".image"));
//		URL imageUrl = null;
//		try {
//			imageUrl =
//				new URL("C:\\sample.gif");
//		} catch (MalformedURLException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		action1.setImageDescriptor(ImageDescriptor.createFromURL(imageUrl));
//		
		action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
			getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK));
		toolBarManager.add(action1);
	}



	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPart#setFocus()
	 */
	public void setFocus() {
		
	}

	/**
	 * mark the given test as passed in the GUI.
	 * 
	 * @param testID
	 */
	public void markTestPassed(String testID) {

		// testid, use it in hashmap to retrieve tree item of test and
		// change icon color, increment pass counter, etc...

		testPool.getTest(testID).setVerdict(Test.PASS);
		

	}

	public void markTestStarted(String testID) {

		

	}

	public void createNewTest(String testName, String testID) {

		testPool.addTest(new Test(testName, testID));
	}

	public void markTestFail(String testID) {
		numFailures++;
		testPool.getTest(testID).setVerdict(Test.FAIL);
		
	}

	public void markTestingStarted(int numTestsToBeRun) {
		
		this.numTests = numTestsToBeRun;
		//reportArea.append("Tests started expecting: " + numTests + " \n");
		
	}

	public void markTestingFinished() {

		
		//reportArea.append("end all tests \n");

	}

	// action to start tests:
	private void startTests() {

		// preparation:
		// take the full test suite (could containt other test suites).
		// create temp php file that starts that suite and uses socketTestReport 
		// as a test result reporter.
		// add listener: localhost , port 13579
		// start listening at port.

		
		listenForReports();
		
		try {
			Runtime.getRuntime().exec("php.exe \"C:/Program Files/Apache Group/Apache2/htdocs/phpUnit/suite.php\"");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 
	 */
	private void listenForReports() {

		ConnectionListener conListener = new ConnectionListener();
		conListener.start(this);

	} //end of method

	/**
	 * handle this report: test passed, faile, end of all.
	 * @param report
	 */
	public void handleReport(String report) {

		//delegate to the XML report handler.		
		handler.handle(report, this);

	}


	/**
	 * @param command
	 * @param testCount
	 * @param testID
	 */
	public void handleCommand(
		String command,
		String testCount,
		String testID) {


		if (command.equals("startAll")) {
		
			 markTestingStarted(new Integer(testCount).intValue());
			 
			
		}else if (command.equals("testStarted")) {

			createNewTest("testName", testID);
			markTestStarted(testID);

		} else if (command.equals("testFINISHED")) {

			markTestFinished();
			
		} else if (command.equals("endAll")) {

			markTestingFinished();
		}


		progressInfoComposite.updateInfo(numTests, numTestsRun, numFailures, numErrors);
		resultsInfoComposite.updateInfo(testPool);

	}

	/**
	 * 
	 */
	private void markTestFinished() {
			
		numTestsRun++;
		
	}

	/**
	 * 
	 */
	private void updateResultsInfo() {
		// TODO Auto-generated method stub
		
	}

	/**
	 * @param currentTestID
	 * @param verdict
	 */
	public void setTestVerdict(String currentTestID, String verdict) {

		if (verdict.equals("passed"))
			markTestPassed(currentTestID);
		else
			markTestFail(currentTestID);

	}

	/**
	 * @param currentTestID
	 * @param exception
	 */
	public void addTestException(String currentTestID, String exception) {

		//TODO: decide how to show exceptions. don't show them for now.
		//reportArea.append("   test " + currentTestID + " exception: " + exception + "\n");

	}

} //end of class