/*
 * Created on Feb 2, 2009
 * Created by Paul Gardner
 *
 * Copyright (C) Azureus Software, Inc, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */


package com.biglybt.ui.swt.devices;

import com.biglybt.core.Core;
import com.biglybt.plugin.net.netstatus.NetStatusPlugin;
import com.biglybt.plugin.net.netstatus.swt.NetStatusPluginTester;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import com.biglybt.core.util.AEThread2;
import com.biglybt.core.util.Debug;
import com.biglybt.pif.PluginInterface;
import com.biglybt.ui.swt.Messages;
import com.biglybt.ui.swt.mainwindow.Colors;
import com.biglybt.ui.swt.pif.UISWTViewEvent;
import com.biglybt.ui.swt.shells.CoreWaiterSWT;
import com.biglybt.ui.swt.shells.CoreWaiterSWT.TriggerInThread;

import com.biglybt.core.CoreRunningListener;
import com.biglybt.core.devices.Device;
import com.biglybt.core.networkmanager.admin.NetworkAdmin;

public class
DeviceInternetView
	extends DeviceManagerUI.categoryView
{
	private DeviceManagerUI		device_manager_ui;

	private NetStatusPlugin plugin;

	private Composite		main;

	private Button			start_button;
	private Button			cancel_button;
	private StyledText 		log;

	private static final int
		selected_tests = 	NetStatusPluginTester.TEST_INBOUND |
							NetStatusPluginTester.TEST_OUTBOUND |
							NetStatusPluginTester.TEST_NAT_PROXIES |
							NetStatusPluginTester.TEST_BIGLYBT_SERVICES |
							NetStatusPluginTester.TEST_PROXY_CONNECT;

	private NetStatusPluginTester		current_test;

	private static final int LOG_NORMAL 	= 1;
	private static final int LOG_SUCCESS 	= 2;
	private static final int LOG_ERROR 		= 3;
	private static final int LOG_INFO 		= 4;

	private int	log_type	= LOG_NORMAL;

	protected
	DeviceInternetView(
		DeviceManagerUI	dm_ui,
		String			title )
	{
		super( dm_ui, Device.DT_INTERNET, title );

		device_manager_ui	= dm_ui;
	}

	public void
	initialize(
		Composite parent )
	{
		PluginInterface pi = device_manager_ui.getPluginInterface().getPluginManager().getPluginInterfaceByClass( NetStatusPlugin.class  );

		plugin = (NetStatusPlugin)pi.getPlugin();

		main = new Composite( parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.marginTop = 4;
		layout.marginBottom = 4;
		layout.marginHeight = 4;
		layout.marginWidth = 4;
		main.setLayout(layout);
		GridData grid_data = new GridData(GridData.FILL_BOTH );
		main.setLayoutData(grid_data);

		Label info_lab = new Label( main, SWT.NONE );

		Messages.setLanguageText( info_lab, "label.test.internet");

			// control

		Composite control = new Composite(main, SWT.NONE);
		layout = new GridLayout();
		layout.numColumns = 3;
		layout.marginHeight = 4;
		layout.marginWidth = 4;
		control.setLayout(layout);

		grid_data = new GridData(GridData.FILL_HORIZONTAL);
		grid_data.horizontalSpan = 1;
		control.setLayoutData(grid_data);

				// start

			start_button = new Button( control, SWT.PUSH );

		 	Messages.setLanguageText( start_button, "ConfigView.section.start");

		 	start_button.addSelectionListener(
		 		new SelectionAdapter()
		 		{
		 			@Override
				  public void
		 			widgetSelected(
		 				SelectionEvent e )
		 			{
		 				start_button.setEnabled( false );

		 				cancel_button.setEnabled( true );

		 				startTest();
		 			}
		 		});

		 		// cancel

		 	cancel_button = new Button( control, SWT.PUSH );

		 	Messages.setLanguageText( cancel_button, "UpdateWindow.cancel");

		 	cancel_button.addSelectionListener(
		 		new SelectionAdapter()
		 		{
		 			@Override
				  public void
		 			widgetSelected(
		 				SelectionEvent e )
		 			{
		 				cancel_button.setEnabled( false );

		 				cancelTest();
		 			}
		 		});

		 	cancel_button.setEnabled( false );


			// log area

		log = new StyledText(main,SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
		grid_data = new GridData(GridData.FILL_BOTH);
		grid_data.horizontalSpan = 1;
		grid_data.horizontalIndent = 4;
		log.setLayoutData(grid_data);
		log.setIndent( 4 );
	}

	protected void
	startTest()
	{
		CoreWaiterSWT.waitForCore(TriggerInThread.NEW_THREAD,
				new CoreRunningListener() {
					@Override
					public void coreRunning(Core core) {
						startTestSupport(core);
					}
				});
	}

	protected void
	cancelTest()
	{
		new AEThread2( "NetStatus:cancel", true )
			{
				@Override
				public void
				run()
				{
					cancelTestSupport();
				}
			}.start();
	}

	protected void
	startTestSupport(
			Core core)
	{
		try{
			synchronized( this ){

				if ( current_test != null ){

					Debug.out( "Test already running!!!!" );

					return;
				}

				int tests = selected_tests;

				if ( NetworkAdmin.getSingleton().isIPV6Enabled()){

					tests |= NetStatusPluginTester.TEST_IPV6;
				}

				current_test =
					new NetStatusPluginTester(
						plugin,
						tests,
						new NetStatusPluginTester.loggerProvider()
						{
							@Override
							public void
							log(
								String 		str,
								boolean		detailed )
							{
								println( str );
							}

							@Override
							public void
							logSuccess(
								String str)
							{
								try{
									log_type = LOG_SUCCESS;

									println( str );

								}finally{

									log_type = LOG_NORMAL;
								}
							}

							@Override
							public void
							logInfo(
								String str)
							{
								try{
									log_type = LOG_INFO;

									println( str );

								}finally{

									log_type = LOG_NORMAL;
								}
							}

							@Override
							public void
							logFailure(
								String str)
							{
								try{
									log_type = LOG_ERROR;

									println( str );

								}finally{

									log_type = LOG_NORMAL;
								}
							}
						});
			}

			println( "Test starting", true );

			current_test.run(core);

			println( current_test.isCancelled()?"Test Cancelled":"Test complete" );

		}catch( Throwable e ){

		}finally{

			try{
				Composite c = main;

				if ( c != null && !c.isDisposed()){

					try{
						c.getDisplay().asyncExec(
							new Runnable()
							{
								@Override
								public void
								run()
								{
									if ( !start_button.isDisposed()){

										start_button.setEnabled( true );
									}

									if ( !cancel_button.isDisposed()){

										cancel_button.setEnabled( false );
									}
								}
							});

					}catch( Throwable e ){
					}
				}
			}finally{

				synchronized( this ){

					current_test.cancel();

					current_test = null;
				}
			}
		}
	}

	protected void
	println(
		String		str )
	{
		print( str + "\n", false );
	}

	protected void
	println(
		String		str,
		boolean		clear_first )
	{
		print( str + "\n", clear_first );
	}

	protected void
	print(
		final String		str,
		final boolean		clear_first )
	{
		if ( !( log.isDisposed() || log.getDisplay().isDisposed())){

			final int f_log_type = log_type;

			log.getDisplay().asyncExec(
					new Runnable()
					{
						@Override
						public void
						run()
						{
							if ( log.isDisposed()){

								return;
							}

							int	start;

							if ( clear_first ){

								start	= 0;

								log.setText( str );

							}else{

								start = log.getText().length();

								log.append( str );
							}

							Color 	color;

							if ( f_log_type == LOG_NORMAL ){

								color = Colors.black;

							}else if ( f_log_type == LOG_SUCCESS ){

								color = Colors.green;

							}else if ( f_log_type == LOG_INFO ){

								color = Colors.blue;

							}else{

								color = Colors.red;
							}

							StyleRange styleRange = new StyleRange();
							styleRange.start = start;
							styleRange.length = str.length();
							styleRange.foreground = color;
							log.setStyleRange(styleRange);

							log.setSelection( log.getText().length());
						}
					});
		}
	}

	protected void
	cancelTestSupport()
	{
		synchronized( this ){

			if ( current_test != null ){

				println( "Cancelling test..." );

				current_test.cancel();
			}
		}
	}

	public Composite
	getComposite()
	{
		return( main );
	}

	@Override
	public boolean eventOccurred(UISWTViewEvent event) {
    switch (event.getType()) {
      case UISWTViewEvent.TYPE_CREATE:
      	//swtView = (UISWTView)event.getData();
        break;

      case UISWTViewEvent.TYPE_DESTROY:
        break;

      case UISWTViewEvent.TYPE_INITIALIZE:
        initialize((Composite)event.getData());
        break;

      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
      	Messages.updateLanguageForControl(getComposite());
        break;

      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
        break;

      case UISWTViewEvent.TYPE_FOCUSGAINED:
      	break;

      case UISWTViewEvent.TYPE_REFRESH:
        break;
    }

    return true;
  }
}
