// CollectionRenderer.java
//
// Created: February 2006
//
// This file is a component of the BioMoby project.
// Copyright Martin Senger (martin.senger@gmail.com).
//

package org.biomoby.service.dashboard.renderers;

import org.biomoby.shared.MobyException;
import org.biomoby.service.dashboard.data.DataContainer;

import org.tulsoft.shared.FileUtils;

import javax.swing.JComponent;

import java.io.File;

/**
 * This is not a normal renderer that is loaded and used through
 * SPI. It is explicitly called if a service result is a collection
 * but no renderer is here to process it as a collection, but there is
 * one or more renderer(s) that can process individual elements of
 * such collection. <p>
 *
 * Various subclasses of this class gets such renderer and a whole
 * collection, and iterates over it - putting resulting components in
 * various layouts (vertically below each other, in a tabbed pane,
 * etc.). <p>
 *
 * Its method {@link #save2File} invents new file name for each
 * element in a collection and calls a specific renderer to save the
 * element in a file. <p>
 *
 * @author <A HREF="mailto:martin.senger@gmail.com">Martin Senger</A>
 * @version $Id: CollectionRenderer.java,v 1.4 2006/02/20 05:51:11 senger Exp $
 */

public abstract class CollectionRenderer
    extends AbstractRenderer {

    protected Renderer renderer;

    /*********************************************************************
     *
     ********************************************************************/
    protected CollectionRenderer (Renderer renderer) {
        super (renderer.getName(), renderer.getIcon());
	this.renderer = renderer;
    }

    /*********************************************************************
     * Never used...
     ********************************************************************/
    public boolean canHandle (String criterion, Object value) {
	return false;
    }

    /*********************************************************************
     *
     ********************************************************************/
    public abstract JComponent getComponent (DataContainer data)
	throws MobyException;

    /**************************************************************************
     * It creates a separate file for each element of the collection
     * in 'data' (it does nothing if 'data' is null, or if it does not
     * contain a collection - an array). It adds a sequential number
     * to the 'file' name: before its extension if the filename has
     * one, or at the end. <p>
     *
     * Note that the real saving is done by a delegate renderer, nit
     * by this class. <p>
     **************************************************************************/
    public boolean save2File (DataContainer data, File file)
	throws MobyException {

	if (data == null)
	    return false;

	Object d = data.getData();
	if (! d.getClass().isArray())
	    return false;

	// prepare for the files naming
	String masterFileName = file.getAbsolutePath();
	int len = masterFileName.length();
	String nameBefore, nameAfter;
	String extension = FileUtils.getExtension (file);
	int extlen = extension.length();
	if (extension.length() == 0) {
	    nameBefore = masterFileName;
	    nameAfter = "";
	} else {
	    nameBefore = masterFileName.substring (0, len - 1 - extlen);
	    nameAfter = masterFileName.substring (len, len - 1 - extlen);
	}

	// save to files
	Object[] ds = (Object[])d;
	for (int i = 0; i < ds.length; i++) {
	    if (! renderer.save2File (new DataContainer (ds[i]),
				      new File (nameBefore +
						"_" + i +
						nameAfter)) )
		return false;
	}
	return true;
    }

}
