/*
 * ImportedTextureWizardTest.java 07 Oct. 2008
 * 
 * Copyright (c) 2008 Emmanuel PUYBARET / eTeks <info@eteks.com>. 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.eteks.sweethome3d.junit;

import java.awt.Component;
import java.awt.Container;
import java.awt.KeyboardFocusManager;
import java.awt.event.InputEvent;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Locale;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;

import junit.extensions.abbot.ComponentTestFixture;
import abbot.finder.AWTHierarchy;
import abbot.finder.BasicFinder;
import abbot.finder.ComponentSearchException;
import abbot.finder.Matcher;
import abbot.finder.matchers.ClassMatcher;
import abbot.finder.matchers.WindowMatcher;
import abbot.tester.JComponentTester;

import com.eteks.sweethome3d.io.FileUserPreferences;
import com.eteks.sweethome3d.model.CatalogTexture;
import com.eteks.sweethome3d.model.Content;
import com.eteks.sweethome3d.model.Home;
import com.eteks.sweethome3d.model.LengthUnit;
import com.eteks.sweethome3d.model.RecorderException;
import com.eteks.sweethome3d.model.TexturesCategory;
import com.eteks.sweethome3d.model.UserPreferences;
import com.eteks.sweethome3d.model.Wall;
import com.eteks.sweethome3d.swing.HomePane;
import com.eteks.sweethome3d.swing.ImportedTextureWizardStepsPanel;
import com.eteks.sweethome3d.swing.PlanComponent;
import com.eteks.sweethome3d.swing.SwingViewFactory;
import com.eteks.sweethome3d.swing.TextureChoiceComponent;
import com.eteks.sweethome3d.swing.WallPanel;
import com.eteks.sweethome3d.swing.WizardPane;
import com.eteks.sweethome3d.tools.URLContent;
import com.eteks.sweethome3d.viewcontroller.ContentManager;
import com.eteks.sweethome3d.viewcontroller.HomeController;
import com.eteks.sweethome3d.viewcontroller.ImportedTextureWizardController;
import com.eteks.sweethome3d.viewcontroller.View;
import com.eteks.sweethome3d.viewcontroller.ViewFactory;
import com.eteks.sweethome3d.viewcontroller.WallController;

/**
 * Tests imported texture wizard.
 * @author Emmanuel Puybaret
 */
public class ImportedTextureWizardTest extends ComponentTestFixture {
  public void testImportedTextureWizard() throws ComponentSearchException, InterruptedException, 
      NoSuchFieldException, IllegalAccessException, InvocationTargetException {
    String language = Locale.getDefault().getLanguage();
    final UserPreferences preferences = new FileUserPreferences() {
        @Override
        public boolean isActionTipIgnored(String actionKey) {
          return true;
        }
      };
    // Ensure we use default language and centimeter unit
    preferences.setLanguage(language);
    preferences.setUnit(LengthUnit.CENTIMETER);
    ViewFactory viewFactory = new SwingViewFactory();
    // Create a dummy content manager
    final URL testedImageName = BackgroundImageWizardTest.class.getResource("resources/test.png");
    final ContentManager contentManager = new ContentManager() {
      public Content getContent(String contentName) throws RecorderException {
        try {
          // Let's consider contentName is a URL
          return new URLContent(new URL(contentName));
        } catch (IOException ex) {
          fail();
          return null;
        }
      }

      public String getPresentationName(String contentName, ContentType contentType) {
        return "test";
      }

      public boolean isAcceptable(String contentName, ContentType contentType) {
        return true;
      }

      public String showOpenDialog(View parentView, String dialogTitle, ContentType contentType) {
        // Return tested model name URL
        return testedImageName.toString();
      }

      public String showSaveDialog(View parentView, String dialogTitle, ContentType contentType, String name) {
        return null;
      }      
    };
    Home home = new Home();
    final HomeController controller = 
        new HomeController(home, preferences, viewFactory, contentManager);
    JComponent homeView = (JComponent)controller.getView();
    PlanComponent planComponent = (PlanComponent)TestUtilities.findComponent(
         homeView, PlanComponent.class);

    // 1. Create a frame that displays a home view 
    JFrame frame = new JFrame("Imported Texture Wizard Test");    
    frame.add(homeView);
    frame.pack();

    // Show home plan frame
    showWindow(frame);
    JComponentTester tester = new JComponentTester();
    tester.waitForIdle();
    // Transfer focus to plan view 
    planComponent.requestFocusInWindow();
    tester.waitForIdle();
    
    // Check plan view has focus
    assertTrue("Plan component doesn't have the focus", planComponent.isFocusOwner());
    
    // 2. Create two wall between points (50, 50), (150, 50) and (150, 150) 
    runAction(controller, HomePane.ActionType.CREATE_WALLS);
    tester.actionClick(planComponent, 50, 50);
    tester.actionClick(planComponent, 150, 50);
    tester.actionClick(planComponent, 150, 150, InputEvent.BUTTON1_MASK, 2);
    runAction(controller, HomePane.ActionType.SELECT);
    // Check two walls were created and selected
    assertEquals("Wrong wall count in home", 2, home.getWalls().size());
    assertEquals("Wrong selected items count in home", 2, home.getSelectedItems().size());
    Iterator<Wall> iterator = home.getWalls().iterator();
    Wall wall1 = iterator.next();
    Wall wall2 = iterator.next();
    // Check walls don't use texture yet
    assertNull("Wrong texture on wall 1 left side", wall1.getLeftSideTexture());
    assertNull("Wrong texture on wall 2 left side", wall2.getLeftSideTexture());
    assertNull("Wrong texture on wall 1 right side", wall1.getRightSideTexture());
    assertNull("Wrong texture on wall 2 right side", wall2.getRightSideTexture());
    
    // 3. Edit walls
    JDialog attributesDialog = showWallPanel(preferences, controller, frame, tester);
    // Retrieve WallPanel components
    WallPanel wallPanel = (WallPanel)TestUtilities.findComponent(
        attributesDialog, WallPanel.class);
    JSpinner xStartSpinner =
        (JSpinner)TestUtilities.getField(wallPanel, "xStartSpinner");
    JSpinner xEndSpinner =
        (JSpinner)TestUtilities.getField(wallPanel, "xEndSpinner");
    TextureChoiceComponent rightSideTextureComponent =
        (TextureChoiceComponent)TestUtilities.getField(wallPanel, "rightSideTextureComponent");
    // Check xStartSpinner and xEndSpinner panels aren't visible
    assertFalse("X start spinner panel is visible", xStartSpinner.getParent().isVisible());
    assertFalse("X end spinner panel is visible", xEndSpinner.getParent().isVisible());
    // Edit right side texture
    JDialog textureDialog = showTexturePanel(preferences, rightSideTextureComponent, false, attributesDialog, tester);
    JList availableTexturesList = (JList)new BasicFinder().find(textureDialog, 
        new ClassMatcher(JList.class, true));
    int textureCount = availableTexturesList.getModel().getSize();
    CatalogTexture defaultTexture = (CatalogTexture)availableTexturesList.getSelectedValue();
    // Import texture
    JDialog textureWizardDialog = showImportTextureWizard(preferences, frame, tester, false);    
    // Retrieve ImportedFurnitureWizardStepsPanel components
    ImportedTextureWizardStepsPanel panel = (ImportedTextureWizardStepsPanel)TestUtilities.findComponent(
        textureWizardDialog, ImportedTextureWizardStepsPanel.class);
    final JButton imageChoiceOrChangeButton = (JButton)TestUtilities.getField(panel, "imageChoiceOrChangeButton");
    final JTextField nameTextField = (JTextField)TestUtilities.getField(panel, "nameTextField");
    JComboBox categoryComboBox = (JComboBox)TestUtilities.getField(panel, "categoryComboBox");
    JSpinner widthSpinner = (JSpinner)TestUtilities.getField(panel, "widthSpinner");
    JSpinner heightSpinner = (JSpinner)TestUtilities.getField(panel, "heightSpinner");
    
    // Check current step is image
    tester.waitForIdle();
    assertStepShowing(panel, true, false);    
    WizardPane view = (WizardPane)TestUtilities.findComponent(textureWizardDialog, WizardPane.class);
    // Check wizard view next button is disabled
    final JButton nextFinishOptionButton = (JButton)TestUtilities.getField(view, "nextFinishOptionButton");
    assertFalse("Next button is enabled", nextFinishOptionButton.isEnabled());
    
    // 4. Choose tested image 
    String imageChoiceOrChangeButtonText = imageChoiceOrChangeButton.getText();
    tester.invokeAndWait(new Runnable() {
        public void run() {
          imageChoiceOrChangeButton.doClick();
        }
      });
    // Wait 200 ms to let time to Java to load the image
    Thread.sleep(200);
    // Check choice button text changed
    assertFalse("Choice button text didn't change", 
        imageChoiceOrChangeButtonText.equals(imageChoiceOrChangeButton.getText()));
    // Click on next button
    tester.invokeAndWait(new Runnable() {
        public void run() {
          nextFinishOptionButton.doClick();
        }
      });
    // Check current step is attributes
    assertStepShowing(panel, false, true);

    // 5. Check default furniture name is the presentation name proposed by content manager
    assertEquals("Wrong default name", 
        contentManager.getPresentationName(testedImageName.toString(), ContentManager.ContentType.IMAGE),
        nameTextField.getText()); 
    // Check name text field has focus
    assertSame("Name text field doesn't have focus", nameTextField,
        KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner());    
    // Check default category is user category  
    String userCategoryName = preferences.getLocalizedString(
        ImportedTextureWizardStepsPanel.class, "userCategory");
    assertEquals("Wrong default category", userCategoryName, 
        ((TexturesCategory)categoryComboBox.getSelectedItem()).getName());
    // Rename texture  
    final String textureTestName = "#@" + System.currentTimeMillis() + "@#";
    tester.invokeAndWait(new Runnable() {
      public void run() {
        nameTextField.setText(textureTestName);    
      }
    });
    // Check next button is enabled again
    assertTrue("Next button isn't enabled", nextFinishOptionButton.isEnabled());

    // 6. Change width with a value 5 times greater
    float width = (Float)widthSpinner.getValue();
    float height = (Float)heightSpinner.getValue();
    widthSpinner.setValue(width * 5);
    // Check height is 5 times greater 
    float newWidth = (Float)widthSpinner.getValue();
    float newHeight = (Float)heightSpinner.getValue();
    assertEquals("width", 5 * width, newWidth);
    assertEquals("height", 5 * height, newHeight);
    
    tester.invokeAndWait(new Runnable() {
        public void run() {
          // Click on Finish to hide dialog box in Event Dispatch Thread
          nextFinishOptionButton.doClick(); 
        }
      });
    assertFalse("Import texture wizard still showing", textureWizardDialog.isShowing());

    // Check the list of available textures has one more selected modifiable texture 
    assertEquals("Wrong texture count in list", textureCount + 1, availableTexturesList.getModel().getSize());
    assertEquals("No selected texture in list", 1, availableTexturesList.getSelectedValues().length);
    CatalogTexture importedTexture = (CatalogTexture)availableTexturesList.getSelectedValue();
    assertNotSame("Wrong selected texture in list", defaultTexture, importedTexture);
    // Check the attributes of the new texture
    assertEquals("Wrong name", textureTestName, importedTexture.getName());
    assertEquals("Wrong category", userCategoryName, importedTexture.getCategory().getName());
    assertEquals("Wrong width", newWidth, importedTexture.getWidth());
    assertEquals("Wrong height", newHeight, importedTexture.getHeight());
    assertTrue("New texture isn't modifiable", importedTexture.isModifiable());
        
    // 7. Click on OK in texture dialog box
    doClickOnOkInDialog(textureDialog, tester);
    // Click on OK in wall dialog box
    doClickOnOkInDialog(attributesDialog, tester);    
    // Check wall attributes are modified accordingly
    assertNull("Wrong texture on wall 1 left side", wall1.getLeftSideTexture());
    assertNull("Wrong texture on wall 2 left side", wall2.getLeftSideTexture());
    assertEquals("Wrong texture on wall 1 right side", textureTestName, wall1.getRightSideTexture().getName());
    assertEquals("Wrong texture on wall 2 right side", textureTestName, wall2.getRightSideTexture().getName());
    
    // 8. Edit left side texture of first wall
    home.setSelectedItems(Arrays.asList(wall1));
    assertEquals("Wrong selected items count in home", 1, home.getSelectedItems().size());
    attributesDialog = showWallPanel(preferences, controller, frame, tester);
    // Retrieve WallPanel components
    wallPanel = (WallPanel)TestUtilities.findComponent(attributesDialog, WallPanel.class);
    xStartSpinner = (JSpinner)TestUtilities.getField(wallPanel, "xStartSpinner");
    xEndSpinner = (JSpinner)TestUtilities.getField(wallPanel, "xEndSpinner");
    TextureChoiceComponent leftSideTextureComponent =
        (TextureChoiceComponent)TestUtilities.getField(wallPanel, "leftSideTextureComponent");
    // Check xStartSpinner and xEndSpinner panels are visible
    assertTrue("X start spinner panel isn't visible", xStartSpinner.getParent().isVisible());
    assertTrue("X end spinner panel isn't visible", xEndSpinner.getParent().isVisible());
    // Edit left side texture
    textureDialog = showTexturePanel(preferences, leftSideTextureComponent, true, attributesDialog, tester);
    availableTexturesList = (JList)new BasicFinder().find(textureDialog, 
        new ClassMatcher(JList.class, true));
    textureCount = availableTexturesList.getModel().getSize();
    // Select imported texture
    availableTexturesList.setSelectedValue(importedTexture, true);
    // Modify texture
    textureWizardDialog = showImportTextureWizard(preferences, frame, tester, true);    
    // Retrieve ImportedFurnitureWizardStepsPanel components
    panel = (ImportedTextureWizardStepsPanel)TestUtilities.findComponent(
        textureWizardDialog, ImportedTextureWizardStepsPanel.class);
    widthSpinner = (JSpinner)TestUtilities.getField(panel, "widthSpinner");
    final JButton nextFinishOptionButton2 = (JButton)TestUtilities.getField(
        TestUtilities.findComponent(textureWizardDialog, WizardPane.class), "nextFinishOptionButton");
    tester.invokeAndWait(new Runnable() {
        public void run() {
          nextFinishOptionButton2.doClick();
        }
      });
    
    // Change width
    widthSpinner.setValue((Float)widthSpinner.getValue() * 2);
    newWidth = (Float)widthSpinner.getValue();
    tester.invokeAndWait(new Runnable() {
        public void run() {
          // Click on Finish to hide dialog box in Event Dispatch Thread
          nextFinishOptionButton2.doClick(); 
        }
      });
    tester.waitForIdle();
    assertFalse("Import texture wizard still showing", textureWizardDialog.isShowing());
    // Check the list of available textures has the same texture count 
    // and a new selected texture 
    assertEquals("Wrong texture count in list", textureCount, availableTexturesList.getModel().getSize());
    assertEquals("No selected texture in list", 1, availableTexturesList.getSelectedValues().length);
    CatalogTexture modifiedTexture = (CatalogTexture)availableTexturesList.getSelectedValue();
    assertNotSame("Wrong selected texture in list", importedTexture, modifiedTexture);
    // Check the attributes of the new texture
    assertEquals("Wrong name", textureTestName, modifiedTexture.getName());
    assertEquals("Wrong category", userCategoryName, modifiedTexture.getCategory().getName());
    assertEquals("Wrong width", newWidth, modifiedTexture.getWidth());
    assertTrue("New texture isn't modifiable", modifiedTexture.isModifiable());

    // 9. Click on OK in texture dialog box
    doClickOnOkInDialog(textureDialog, tester);
    // Click on OK in wall dialog box
    doClickOnOkInDialog(attributesDialog, tester);    
    // Check wall attributes are modified accordingly
    assertEquals("Wrong texture on wall 1 left side", newWidth, wall1.getLeftSideTexture().getWidth());
    assertNull("Wrong texture on wall 2 left side", wall2.getLeftSideTexture());
    assertEquals("Wrong texture on wall 1 right side", newWidth / 2, wall1.getRightSideTexture().getWidth());
    assertEquals("Wrong texture on wall 2 right side", newWidth / 2, wall2.getRightSideTexture().getWidth());
    
    // 10. Open wall dialog a last time to delete the modified texture
    attributesDialog = showWallPanel(preferences, controller, frame, tester);
    // Retrieve WallPanel components
    wallPanel = (WallPanel)TestUtilities.findComponent(attributesDialog, WallPanel.class);
    leftSideTextureComponent = (TextureChoiceComponent)TestUtilities.getField(wallPanel, "leftSideTextureComponent");
    // Edit left side texture
    textureDialog = showTexturePanel(preferences, leftSideTextureComponent, true, attributesDialog, tester);
    availableTexturesList = (JList)new BasicFinder().find(textureDialog, 
        new ClassMatcher(JList.class, true));
    textureCount = availableTexturesList.getModel().getSize();
    // Select modified texture
    availableTexturesList.setSelectedValue(modifiedTexture, true);
    final JButton deleteButton = (JButton)new BasicFinder().find(textureDialog, 
        new Matcher() {
          public boolean matches(Component c) {
            return c instanceof JButton && ((JButton)c).getText().equals(preferences.getLocalizedString(
                TextureChoiceComponent.class, "deleteTextureButton.text"));
          }
        });
    tester.invokeAndWait(new Runnable() { 
        public void run() {
          // Display confirm dialog box later in Event Dispatch Thread to avoid blocking test thread
          deleteButton.doClick();        
        }
      });
    tester.waitForIdle();
    // Wait for confirm dialog to be shown
    final String confirmDeleteSelectedCatalogTextureDialogTitle = preferences.getLocalizedString(
        TextureChoiceComponent.class, "confirmDeleteSelectedCatalogTexture.title");
    tester.waitForFrameShowing(new AWTHierarchy(), confirmDeleteSelectedCatalogTextureDialogTitle);
    // Check dialog box is displayed
    JDialog confirmDialog = (JDialog)new BasicFinder().find(textureDialog,  
        new Matcher() {
            public boolean matches(Component c) {
              return c instanceof JDialog && ((JDialog)c).getTitle().equals(
                  confirmDeleteSelectedCatalogTextureDialogTitle);
            }
          });
    assertTrue("Confirm dialog not showing", confirmDialog.isShowing());
    doClickOnOkInDialog(confirmDialog, tester);
    tester.waitForIdle();
    // Check the list of available textures has one less texture and no selected texture 
    assertEquals("Wrong texture count in list", textureCount - 1, availableTexturesList.getModel().getSize());
    assertEquals("No selected texture in list", 0, availableTexturesList.getSelectedValues().length);
    // Check delete button is disabled
    assertFalse("Delete button isn't disabled", deleteButton.isEnabled());
    // Click on OK in texture dialog box
    doClickOnOkInDialog(textureDialog, tester);
    // Click on OK in wall dialog box
    doClickOnOkInDialog(attributesDialog, tester);    
    // Check wall attributes didn't change
    assertNotNull("Wrong texture on wall 1 left side", wall1.getLeftSideTexture());
    assertNull("Wrong texture on wall 2 left side", wall2.getLeftSideTexture());
    assertNotNull("Wrong texture on wall 1 right side", wall1.getRightSideTexture());
    assertNotNull("Wrong texture on wall 2 right side", wall2.getRightSideTexture());
  }

  /**
   * Returns the dialog that displays wall attributes. 
   */
  private JDialog showWallPanel(UserPreferences preferences,
                                final HomeController controller, 
                                JFrame parent, JComponentTester tester) 
            throws ComponentSearchException {
    tester.invokeLater(new Runnable() { 
        public void run() {
          // Display dialog box later in Event Dispatch Thread to avoid blocking test thread
          runAction(controller, HomePane.ActionType.MODIFY_WALL);
        }
      });
    // Wait for wall view to be shown
    tester.waitForFrameShowing(new AWTHierarchy(), preferences.getLocalizedString(
        WallPanel.class, "wall.title"));
    // Check dialog box is displayed
    JDialog attributesDialog = (JDialog)new BasicFinder().find(parent, 
        new ClassMatcher (JDialog.class, true));
    assertTrue("Wall dialog not showing", attributesDialog.isShowing());
    return attributesDialog;
  }
  
  /**
   * Returns the dialog that displays texture panel. 
   */
  private JDialog showTexturePanel(UserPreferences preferences,
                                   final TextureChoiceComponent textureComponent, 
                                   boolean leftSide,
                                   Container parent, JComponentTester tester) 
            throws ComponentSearchException {
    tester.invokeLater(new Runnable() { 
        public void run() {
          // Display dialog box later in Event Dispatch Thread to avoid blocking test thread
          textureComponent.doClick();        }
      });
    // Wait for texture panel to be shown
    String textureTitle = preferences.getLocalizedString(
        WallController.class, leftSide ? "leftSideTextureTitle" : "rightSideTextureTitle");
    tester.waitForFrameShowing(new AWTHierarchy(), textureTitle);
    // Check texture dialog box is displayed
    JDialog textureDialog = (JDialog)new BasicFinder().find(parent, 
        new WindowMatcher(textureTitle));
    assertTrue("Texture dialog not showing", textureDialog.isShowing());
    return textureDialog;
  }

  /**
   * Returns the dialog that displays texture import wizard. 
   */
  private JDialog showImportTextureWizard(final UserPreferences preferences,
                                          Container parent, JComponentTester tester, 
                                          final boolean modify) 
            throws ComponentSearchException {
    final JButton button = (JButton)new BasicFinder().find(parent, 
        new Matcher() {
          public boolean matches(Component c) {
            return c instanceof JButton 
                && ((JButton)c).getText() != null 
                && ((JButton)c).getText().equals(preferences.getLocalizedString(
                    TextureChoiceComponent.class,
                    modify ? "modifyTextureButton.text" : "importTextureButton.text"));
          }
        });
    tester.invokeLater(new Runnable() { 
        public void run() {
          // Display dialog box later in Event Dispatch Thread to avoid blocking test thread
          button.doClick();        
        }
      });
    // Wait for texture wizard to be shown
    String textureWizardTitle = preferences.getLocalizedString(
        ImportedTextureWizardController.class,
        modify ? "modifyTextureWizard.title" : "importTextureWizard.title");
    tester.waitForFrameShowing(new AWTHierarchy(), textureWizardTitle);
    // Check texture dialog box is displayed
    JDialog textureDialog = (JDialog)new BasicFinder().find(parent, 
        new WindowMatcher(textureWizardTitle));
    assertTrue("Texture wizard not showing", textureDialog.isShowing());
    return textureDialog;
  }

  /**
   * Clicks on OK in dialog to close it.
   */
  private void doClickOnOkInDialog(JDialog dialog, JComponentTester tester) 
            throws ComponentSearchException {
    final JOptionPane attributesOptionPane = (JOptionPane)TestUtilities.findComponent(
        dialog, JOptionPane.class);
    tester.invokeAndWait(new Runnable() {
        public void run() {
          // Select Ok option to hide dialog box in Event Dispatch Thread
          if (attributesOptionPane.getOptions() != null) {
            attributesOptionPane.setValue(attributesOptionPane.getOptions() [0]);
          } else {
            attributesOptionPane.setValue(JOptionPane.OK_OPTION);
          }
        }
      });
    assertFalse("Dialog still showing", dialog.isShowing());
  }

  /**
   * Runs <code>actionPerformed</code> method matching <code>actionType</code> 
   * in <code>HomePane</code>. 
   */
  private void runAction(HomeController controller,
                         HomePane.ActionType actionType) {
    ((JComponent)controller.getView()).getActionMap().get(actionType).actionPerformed(null);
  }

  /**
   * Asserts if each <code>panel</code> step preview component is showing or not. 
   */
  private void assertStepShowing(ImportedTextureWizardStepsPanel panel,
                                 boolean imageStepShwing,
                                 boolean attributesStepShowing) throws NoSuchFieldException, IllegalAccessException {    
    assertEquals("Wrong image step visibility", imageStepShwing,
        ((JComponent)TestUtilities.getField(panel, "imageChoicePreviewComponent")).isShowing());
    assertEquals("Wrong attributes step visibility", attributesStepShowing,
        ((JComponent)TestUtilities.getField(panel, "attributesPreviewComponent")).isShowing());
  }
}
