/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class StatusWindow extends JFrame 
{

	private JProgressBar progressBar = null;
	private JTextField statusLabel = null;
	private JButton cancelButton = null;
	private JFrame statusWindow = null;
	private PostNewsgroup mainWindow = null;

	private final int MAXPROGRESS = 13;
	private final int MINPROGRESS = 0;


	public StatusWindow( PostNewsgroup mw, String title, int parentX, int parentY )
	{
		this.setTitle( title );
		this.setLocation( parentX + 100, parentY + 100 );
		statusWindow = this;
		mainWindow = mw;

		mainWindow.enableButtons( false );

		statusWindow.addWindowListener( new WindowAdapter()
		{
			public void windowClosing( WindowEvent event ) {
				mainWindow.enableButtons( true );	
			}
		});

		progressBar = new JProgressBar();
		progressBar.setStringPainted( true );
		progressBar.setMaximum( MAXPROGRESS );
		progressBar.setMinimum( MINPROGRESS );
		progressBar.setSize( 30, 400 );

		JLabel progLabel = new JLabel( "Progress:" );

		JPanel progressPanel = new JPanel();
		progressPanel.setLayout( new BorderLayout( 10, 0 ) );
		progressPanel.add( progLabel, "West" );
		progressPanel.add( progressBar, "East" );

		statusLabel = new JTextField();
		statusLabel.setColumns( 25 );
		statusLabel.setEditable( false );
		statusLabel.setBorder( null );
		//statusLabel.setBorder( LineBorder.createGrayLineBorder() );
		JPanel statusPanel = new JPanel();
		//statusPanel.setBorder( LineBorder.createBlackLineBorder() );
		statusPanel.setLayout( new BorderLayout() );
		statusPanel.add( statusLabel, "West" );

		cancelButton = new JButton( "Cancel" );
		cancelButton.setSize( 30, 100 );
		cancelButton.setEnabled( false );
		cancelButton.addActionListener( new ActionListener()
		{
                        public void actionPerformed( ActionEvent event ) {
                                // cancelling actions
				mainWindow.enableButtons( true );
				statusWindow.dispose();
                        }
                });

		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout( new BorderLayout( 0, 5 ) );
		buttonPanel.add( cancelButton, "East" );
		buttonPanel.add( new JSeparator( SwingConstants.HORIZONTAL ), "North" );

		Container container = getContentPane();
		container.setLayout( new GridBagLayout() );
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.fill = GridBagConstraints.BOTH;
		
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.gridwidth = 1;
		constraints.gridheight = 1;	
		constraints.insets = new Insets( 15, 15, 10, 15 );
		container.add( progressPanel, constraints );

		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.gridwidth = 1;
		constraints.gridheight = 1;	
		constraints.insets = new Insets( 10, 15, 10, 15 );
		container.add( statusPanel, constraints );

		constraints.gridx = 0;
		constraints.gridy = 2;
		constraints.gridwidth = 1;
		constraints.gridheight = 1;	
		constraints.insets = new Insets( 10, 15, 5, 15 );
		container.add( buttonPanel, constraints );

		this.pack();
		this.setResizable( false );
		//this.setVisible( true );

	}

	
	public void setStatus( int progress, String status )
	{
		progressBar.setValue( progress );
		statusLabel.setText( status );
		statusLabel.setToolTipText( status );
		if( progress == MAXPROGRESS )
		{
                	cancelButton.setEnabled( true );
                	cancelButton.setText( "Close" );
		}
		update( getGraphics() );
		mainWindow.update( mainWindow.getGraphics() );
	}
	
	
	public void enableCancelButton( boolean enable )
	{
		if( enable )
		{
			cancelButton.setEnabled( true );
			cancelButton.setText( "Finish" );
		}
		else
		{
			cancelButton.setEnabled( false );
			cancelButton.setText( "Cancel" );
		}

	}

}
