/**
 * @(#)FCConverter.java	29.06.2004
 *
 * Copyright 2004 Edgar Soldin
 * 
 * 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 de.soldin.gt2jump.readwrite;

import java.util.Iterator;

import com.vividsolutions.jump.feature.AttributeType;
import com.vividsolutions.jump.feature.BasicFeature;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.feature.FeatureCollection;
import com.vividsolutions.jump.feature.FeatureDataset;
import com.vividsolutions.jump.feature.FeatureSchema;

/**
 * A converter between geotools2 {@link org.geotools.feature.FeatureCollection} and
 * jumps {@link com.vividsolutions.jump.feature.FeatureCollection}. Unfortunately
 * not all details can be converted because of design incompatibilities. (see PROBLEMS)
 * <p>
 * This is tested and works relatively stable with the Shape File Reader of the GT2 package.
 * </p>
 *
 * PROBLEMS: Writing and reading of FIDs is not currently implemented
 * as jump FIDs are integer and GT2's are string
 */
public class FCConverter{

	public static org.geotools.feature.FeatureCollection convert(com.vividsolutions.jump.feature.FeatureCollection jump_features) throws Exception{
		// GT2 feature collection
		org.geotools.feature.FeatureCollection gt2_features = 
						org.geotools.feature.FeatureCollections.newCollection();
		
		for (Iterator iter = jump_features.iterator(); iter.hasNext();) {
			Feature jump_feature = (Feature) iter.next();
			
			// get jump_schema for feature
			FeatureSchema jump_fschema = jump_feature.getSchema();
			// create a feature schema for GT2
			org.geotools.feature.FeatureTypeFactory gt2_ftype_factory = org.geotools.feature.FeatureTypeFactory.newInstance(Integer.toString(jump_feature.getID()));
			// create an array of GT2 Attribs
			Object[] gt2_attribs = new Object[jump_fschema.getAttributeCount()];
			
			for (int i = 0; i<jump_fschema.getAttributeCount(); i++){
				
				// building schema
				AttributeType a_type = jump_fschema.getAttributeType(i);
				
				org.geotools.feature.AttributeType gt2_a_type = 
					org.geotools.feature.AttributeTypeFactory.newAttributeType(
													jump_fschema.getAttributeName(i),
													a_type.toJavaClass());
				gt2_ftype_factory.addType(gt2_a_type);
				
				// adding attrib
				gt2_attribs[i] = jump_feature.getAttribute(i);
						
			}
			
			//System.out.println(gt2_ftype_factory.toString());
			org.geotools.feature.FeatureType gt2_ftype = gt2_ftype_factory.getFeatureType();
			
			// create GT2 feature
			String fid = Integer.toString(jump_feature.getID());
			org.geotools.feature.Feature gt2_feature = gt2_ftype.create(gt2_attribs,fid);
			
			// add it to collection
			gt2_features.add(gt2_feature);
			
		}
		
		return gt2_features;
	}

	public static com.vividsolutions.jump.feature.FeatureCollection convert(org.geotools.feature.FeatureCollection gt2_features){
		// jump feature collection
		FeatureCollection result = null;
		// a schema for the jump feature collection (what does jump need it for?) 
		FeatureSchema jump_fctype = null;
		
		for (Iterator iter = gt2_features.iterator(); iter.hasNext();) {
			org.geotools.feature.Feature gt2_feature = (org.geotools.feature.Feature) iter.next();
			
			// create jump_schema for feature
			FeatureSchema jump_fschema = new FeatureSchema();
			//jump_fschema.addAttribute("GEOMETRY", AttributeType.GEOMETRY);
			org.geotools.feature.FeatureType gt2_ftype = gt2_feature.getFeatureType();
			for (int i = 0; i<gt2_ftype.getAttributeCount(); i++){
				org.geotools.feature.AttributeType a_type = gt2_ftype.getAttributeType(i);
				// add to feature schema
				//System.out.println("<"+a_type.getName()+"("+a_type.getType().getName()+"):>");
				if (a_type.isGeometry())
					jump_fschema.addAttribute( a_type.getName(), AttributeType.GEOMETRY );
				else
					jump_fschema.addAttribute( a_type.getName(), AttributeType.toAttributeType( a_type.getType() ) );
			}
			//if (jump_fctype==null) jump_fctype = (FeatureSchema)jump_fschema.clone();
			
			
			// create jump_feature 
			Feature jump_feature = new BasicFeature(jump_fschema);
			Object[] gt2_attribs = gt2_feature.getAttributes(null);
			for (int i = 0; i < gt2_attribs.length; i++) {
				Object attrib = gt2_attribs[i];
				//System.out.print("<" + jump_fschema.getAttributeName(i)+"("+jump_fschema.getAttributeType(i)+"):"+attrib.toString() + ">");
				jump_feature.setAttribute(jump_fschema.getAttributeIndex(jump_fschema.getAttributeName(i)), attrib );
			}
			//System.out.println();
			
			// create feature_collection if not existing
			// ATTENTION: jump seems to handle only ONE consistent schema per collection
			if ( result == null ) result = new FeatureDataset(jump_fschema);
			result.add(jump_feature);
		
		}
		
		// never return null 
		if ( result == null ) result = new FeatureDataset(new FeatureSchema());
		gt2_features = null;
		System.gc();
		
		return result;	
	}
	

	public static FeatureSchema convert(org.geotools.feature.FeatureType gt2_ftype){
		FeatureSchema jump_fschema = new FeatureSchema();
		for (int i = 0; i<gt2_ftype.getAttributeCount(); i++){
			org.geotools.feature.AttributeType a_type = gt2_ftype.getAttributeType(i);
			// add to feature schema
			//System.out.println("<"+a_type.getName()+"("+a_type.getType().getName()+"):>");
			if (a_type.isGeometry())
				jump_fschema.addAttribute( a_type.getName(), AttributeType.GEOMETRY );
			else
				jump_fschema.addAttribute( a_type.getName(), AttributeType.toAttributeType( a_type.getType() ) );
		}
		return jump_fschema;		
	}

}




