//$Id: XMLGenerator.java,v 1.7 2002/05/30 21:18:25 egonzalez Exp $
package com.icard.xml;

import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.io.File; 

import com.icard.voucher.Voucher;
import com.icard.voucher.VoucherGener;
import com.icard.voucher.VoucherImprimible;

public class XMLGenerator
{
	public static final String uri = "/usr/local/assistcard/com/icard/xml/voucher.xml";
	public static final String xsluri = "/usr/local/assistcard/com/icard/xml/voucher.xsl";
	//public static final String uri = "./voucher.xml";

	public XMLGenerator()
	{
	}

	/**
	 *
	 */
	public Document getXSL( )
	{
		Document template = null;

		//First, lets parse the templateument
		try
		{
			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			template = parser.parse( xsluri );
		}
		catch( Exception e )
		{
			System.err.println("Sorry, error ocurred " + e );
		}
		return template;
	}	
	/**
	 * Returns the XML document
	 */
	public Document getDocument( String url )
	{
		Document template = null;

		//First, lets parse the templateument
		try
		{
			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			template = parser.parse( url );
		}
		catch( Exception e )
		{
			System.err.println("Sorry, error ocurred " + e );
		}
		return template;
	}	


	/**
	 *
	 */
	//public Document generateVoucher( VoucherGener voucher )
	public Document generateVoucher( VoucherGener voucher )
	{
		System.err.println("GENERATING VOUCHER ---");

		Document template = null;

		//First, lets parse the templateument
		try
		{
			//DOMParser parser = new DOMParser();
			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			template = parser.parse( uri );
			//parseAndPrint( template );
		}
		catch( Exception e )
		{
			System.err.println("Sorry, error ocurred " + e );
		}
		try
		{
			NodeList rootList = template.getElementsByTagName("vouchers");
			Node rootNode = rootList.item(0); // The root as a Node 
			Element rootElement = (Element)rootNode; // the root as an Element

			Node voucherNode = ((Element)rootElement.getElementsByTagName("voucher").item(0));
			Element voucherElement = (Element) voucherNode;

			ArrayList vouchers = voucher.getVoucherImprimibles();
			for( Iterator i = vouchers.iterator(); i.hasNext(); )
			{
				VoucherImprimible v = (VoucherImprimible)i.next();
				//VoucherImprimible v = null;
				Node vou = voucherElement.cloneNode( true );
				//rootNode.appendChild( createVoucherXML( vou, v ) );
				rootNode.replaceChild( createVoucherXML( vou, v ), voucherElement );
			}
			parseAndPrint( template );

			//String xml = null;
			//TransformerFactoryImpl transformer = new TransformerFactoryImpl();
			//Transformer trans = transformer.newInstance().newTransformer();
			//transformer.setOutputProperty( OutputKeys.ENCODING, "ISO-8859-1");
			//ByteArrayOutputStream array = new ByteArrayOutputStream();
			//trans.transform( new DOMSource( rootNode ), new StreamResult( array ) );
			//xml = array.toString();
			//System.out.println(xml);
		}
		catch( Exception e )
		{	
			//do something
			System.err.println("Whoops, error ocurred " + e );
			e.printStackTrace();
		}
		System.err.println("END OF GENERATING VOUCHER ---");

		return null;
	}

	private Node createVoucherXML( Node clonedVoucher, VoucherImprimible v )
	{
		Element voucherElement = (Element)clonedVoucher;

		//Let's set the vouchers attrs
		setVoucherAttr( voucherElement, v );

		//Let's insert the CLIENTE data into the xml
		insertClienteIntoXML( voucherElement, v );

		//Let's modify the AGENCIA data
		Element agenciaElement = (Element) voucherElement.getElementsByTagName("agencia").item(0);
		setValueByNode( agenciaElement.getElementsByTagName("pais").item(0), 
			""+v.agencia.getPais());
		setValueByNode( agenciaElement.getElementsByTagName("codigo").item(0), 
			""+v.agencia.getCodigo());
		setValueByNode( agenciaElement.getElementsByTagName("codigoSuc").item(0), 
			""+v.agencia.getCodigoSuc());
		setValueByNode( agenciaElement.getElementsByTagName("nombre_comercial").item(0), 
			""+v.agencia.getNombreComercial());

		//Let's modify the PRODUCTO data
		Element productoElement = (Element) voucherElement.getElementsByTagName("producto").item(0);
		setValueByNode( productoElement.getElementsByTagName("pais").item(0),
			""+v.producto.getPais());
		setValueByNode( productoElement.getElementsByTagName("codigo").item(0), 
			""+v.producto.getCodigo());
		setValueByNode( productoElement.getElementsByTagName("nombre").item(0), 
			""+v.producto.getNombre());

		//Let's modify the SEGURO data	
		insertSeguroIntoXML( voucherElement, v );
		
		//Let's modify the SEGE data
		insertSeguroEmitidoIntoXML( voucherElement, v );

		//Let's modify the TARIFA data
		insertTarifaIntoXML( voucherElement, v );

		return clonedVoucher;
	}

	/**
	 * This method sets all voucher attrs
	 */
	private void setVoucherAttr( Element voucherElement, VoucherImprimible v )
	{
		(voucherElement.getAttributeNode("fec_vig_fin")).setValue(v.voucher.getFecVifFin().toString());
		(voucherElement.getAttributeNode("fec_vig_inic")).setValue(v.voucher.getFecVigInic().toString());

		(voucherElement.getAttributeNode("tax_impuesto")).setValue(
			"" + ( v.voucher.getTaxImpresa() - v.voucher.getTarifaImpresa() )
		);

		(voucherElement.getAttributeNode("cant_dias")).setValue( "" + v.voucher.getCantDias());
		(voucherElement.getAttributeNode("tax_emitida")).setValue("" + v.voucher.getTaxEmitida());
		(voucherElement.getAttributeNode("tarifa_impresa")).setValue(""+v.voucher.getTarifaImpresa());
		(voucherElement.getAttributeNode("fecha_emision")).setValue(""+v.voucher.getFechaEmision());
		(voucherElement.getAttributeNode("cod_tarifa")).setValue(""+v.voucher.getCodTarifa());
		(voucherElement.getAttributeNode("codigo")).setValue(""+v.voucher.getCodigo());
		(voucherElement.getAttributeNode("pais")).setValue(""+v.voucher.getPais());
		(voucherElement.getAttributeNode("area")).setValue(""+v.voucher.getArea());
		(voucherElement.getAttributeNode("tipo_pax_voucher")).setValue(""+v.voucher.getTipoPaxVoucher());
		(voucherElement.getAttributeNode("sufijo_voucher")).setValue(""+v.voucher.getSufijoVoucher());
	}

	/**
	 * Inserts the CLIENTE data into the XML
	 */
	private void insertClienteIntoXML( Element voucherElement, VoucherImprimible v)
	{
		//Let's modify the CLIENTE data
		Node clienteNode = voucherElement.getElementsByTagName("cliente").item(0);
		Element clienteElement = (Element) clienteNode;
		
		setValueByNode( clienteElement.getElementsByTagName("pais").item(0), 
			"" + v.cliente.getPais());
		setValueByNode( clienteElement.getElementsByTagName("codigo").item(0), 
			"" + v.cliente.getCodigo());
		setValueByNode( clienteElement.getElementsByTagName("apellido").item(0), 
			v.cliente.getApellido());
		setValueByNode( clienteElement.getElementsByTagName("nombre").item(0), 
			v.cliente.getNombre());
		setValueByNode( clienteElement.getElementsByTagName("sexo").item(0), 
			v.cliente.getSexo());
		setValueByNode( clienteElement.getElementsByTagName("fec_nacimiento").item(0), 
			( v.cliente.getFecNacimiento() ).toString() );
		setValueByNode( clienteElement.getElementsByTagName("edad").item(0), 
			"" + v.cliente.getEdad() );
		setValueByNode( clienteElement.getElementsByTagName("pasaporte").item(0), 
			v.cliente.getPasaporte());

		setValueByNode( clienteElement.getElementsByTagName("tel_particular").item(0), 
			v.cliente.getTelParticular());
		setValueByNode( clienteElement.getElementsByTagName("dom_calle").item(0),
			v.cliente.getDomCalle());
		setValueByNode( clienteElement.getElementsByTagName("dom_nro").item(0), 
			v.cliente.getDomNro());
		setValueByNode( clienteElement.getElementsByTagName("dom_cp").item(0), 
			v.cliente.getDomCp());
		setValueByNode( clienteElement.getElementsByTagName("dom_ciudad").item(0), 
			v.cliente.getDomCiudad());

		setValueByNode( clienteElement.getElementsByTagName("dom_pais").item(0), 
			"" + v.cliente.getDomPais());
		setValueByNode( clienteElement.getElementsByTagName("emer_contacto").item(0), 
			v.cliente.getEmergContacto());
		setValueByNode( clienteElement.getElementsByTagName("emerg_calle").item(0), 
			v.cliente.getEmergCalle());
		setValueByNode( clienteElement.getElementsByTagName("emerg_nro").item(0), 
			v.cliente.getEmergNro());
		setValueByNode( clienteElement.getElementsByTagName("emerg_piso").item(0), 
			v.cliente.getEmergPiso());
		setValueByNode( clienteElement.getElementsByTagName("emerg_puerta").item(0), 
			v.cliente.getEmergPuerta());
		setValueByNode( clienteElement.getElementsByTagName("emerg_cp").item(0), 
			v.cliente.getEmergCp());
		setValueByNode( clienteElement.getElementsByTagName("emerg_ciudad").item(0), 
			v.cliente.getEmergCiudad());
		setValueByNode( clienteElement.getElementsByTagName("emerg_prov").item(0), 
			v.cliente.getEmergProv());
		setValueByNode( clienteElement.getElementsByTagName("emerg_pais").item(0), 
			"" + v.cliente.getEmergPais());
		setValueByNode( clienteElement.getElementsByTagName("emerg_tel1").item(0), 
			v.cliente.getEmergTel1());
		setValueByNode( clienteElement.getElementsByTagName("emerg_tel2").item(0), 
			v.cliente.getEmergTel2());
		setValueByNode( clienteElement.getElementsByTagName("emerg_email").item(0), 
			v.cliente.getEmergEmail());

	}	

	/**
	 * Inserts the TARIFA data into the XML
	 */
	private void insertTarifaIntoXML( Element voucherElement, VoucherImprimible v)
	{
		//Let's modify the TARIFA data
		Element tarifaElement = (Element)voucherElement.getElementsByTagName("tarifa").item(0);

		if( v.tarifa != null )
		{
			setValueByNode( tarifaElement.getElementsByTagName("pais").item(0), ""+v.tarifa.getPais());
			setValueByNode( tarifaElement.getElementsByTagName("producto").item(0), ""+v.tarifa.getProducto());
			setValueByNode( tarifaElement.getElementsByTagName("tarifa").item(0), ""+v.tarifa.getTarifa());
			setValueByNode( tarifaElement.getElementsByTagName("cantDias").item(0), ""+v.tarifa.getCantDias());
			setValueByNode( tarifaElement.getElementsByTagName("leyenda").item(0), ""+v.tarifa.getLeyenda());
		}
		else
		{
			setValueByNode( tarifaElement.getElementsByTagName("pais").item(0), "");
			setValueByNode( tarifaElement.getElementsByTagName("producto").item(0), "");
			setValueByNode( tarifaElement.getElementsByTagName("tarifa").item(0), "");
			setValueByNode( tarifaElement.getElementsByTagName("cantDias").item(0), "");
			setValueByNode( tarifaElement.getElementsByTagName("leyenda").item(0), "");
		}
	}	

	/**
	 * Inserts the SEGURO EMITIDO data into the XML
	 */
	private void insertSeguroEmitidoIntoXML( Element voucherElement, VoucherImprimible v)
	{
		//Let's modify the SEGUROEMITIDO data
		Element seguroEElement = (Element)voucherElement.getElementsByTagName("seguroEmitido").item(0);

		if( v.sege != null )
		{
			setValueByNode( seguroEElement.getElementsByTagName("pais").item(0),
				""+v.sege.getPais());
			setValueByNode( seguroEElement.getElementsByTagName("codigo").item(0),
				""+v.sege.getCodigo());
			setValueByNode( seguroEElement.getElementsByTagName("nroVoucher").item(0),
				""+v.sege.getNroVoucher());
			setValueByNode( seguroEElement.getElementsByTagName("nro_certificado").item(0),
				""+v.sege.getNroCertificado());
			setValueByNode( seguroEElement.getElementsByTagName("cod_cia_seguros").item(0),
				""+v.sege.getCodCiaSeguros());
			setValueByNode( seguroEElement.getElementsByTagName("nro_recibo").item(0),
				""+v.sege.getNroRecibo());
			setValueByNode( seguroEElement.getElementsByTagName("fec_recibo").item(0),
				""+v.sege.getFecRecibo());
		}
		else
		{
			setValueByNode( seguroEElement.getElementsByTagName("pais").item(0),
				"");
			setValueByNode( seguroEElement.getElementsByTagName("codigo").item(0),
				"");
			setValueByNode( seguroEElement.getElementsByTagName("nroVoucher").item(0),
				"");
			setValueByNode( seguroEElement.getElementsByTagName("nro_certificado").item(0),
				"");
			setValueByNode( seguroEElement.getElementsByTagName("cod_cia_seguros").item(0),
				"");
			setValueByNode( seguroEElement.getElementsByTagName("nro_recibo").item(0),
				"");
			setValueByNode( seguroEElement.getElementsByTagName("fec_recibo").item(0),
				"");
		}
	}	

	/**
	 * Inserts the CLIENTE data into the XML
	 */
	private void insertSeguroIntoXML( Element voucherElement, VoucherImprimible v)
	{
		//Let's modify the SEGURO data
		Element seguroElement = (Element)voucherElement.getElementsByTagName("seguro").item(0);

		if( v.seg != null )
		{
			setValueByNode( seguroElement.getElementsByTagName("pais").item(0), 
				""+v.seg.getPais());
			setValueByNode( seguroElement.getElementsByTagName("codigo").item(0), 
				""+v.seg.getCodigo());
			setValueByNode( seguroElement.getElementsByTagName("tipoSeguro").item(0), 
				""+v.seg.getTipoSeguro());
			setValueByNode( seguroElement.getElementsByTagName("nombre").item(0),
				""+v.seg.getNombre());
			setValueByNode( seguroElement.getElementsByTagName("poliza").item(0),
				""+v.seg.getPoliza());
			setValueByNode( seguroElement.getElementsByTagName("tope_aereo").item(0),
				""+v.seg.getTopeAereo());
			setValueByNode( seguroElement.getElementsByTagName("tope_terrestre").item(0),
				""+v.seg.getTopeTerrestre());
			setValueByNode( seguroElement.getElementsByTagName("tope").item(0),
				""+v.seg.getTope());
			setValueByNode( seguroElement.getElementsByTagName("total").item(0), 
				""+v.seg.getTopeAereo() + v.seg.getTopeTerrestre());
		}
		else
		{
			setValueByNode( seguroElement.getElementsByTagName("pais").item(0), 
				"");
			setValueByNode( seguroElement.getElementsByTagName("codigo").item(0), 
				"");
			setValueByNode( seguroElement.getElementsByTagName("tipoSeguro").item(0), 
				"");
			setValueByNode( seguroElement.getElementsByTagName("nombre").item(0),
				"");
			setValueByNode( seguroElement.getElementsByTagName("poliza").item(0),
				"");
			setValueByNode( seguroElement.getElementsByTagName("tope_aereo").item(0),
				"");
			setValueByNode( seguroElement.getElementsByTagName("tope_terrestre").item(0),
				"");
			setValueByNode( seguroElement.getElementsByTagName("tope").item(0),
				"");
			setValueByNode( seguroElement.getElementsByTagName("total").item(0), 
				"");
		}
	}
	/**
	 * Sets a tag's value by given node.
	 *
	 * @param     n             the node of the tag
	 * @param     value_new     the new value for the tag
	 * @return    value_old     the old value of the tag in a string
	 *
	 */
	private String setValueByNode(Node n, String value_new)
	{
		String value_old = "";

		if (null != n)
		{
			NodeList nl = n.getChildNodes();
			Node cn = null;
			int type = -1;
			int len = nl.getLength();
			for ( int i = 0; i < len; i++ )
			{
				cn = nl.item(i);
				type = cn.getNodeType();
				if ( type == Node.TEXT_NODE )
				{
					value_old = cn.getNodeValue();
					cn.setNodeValue(value_new);
					break;
				}
			}
		}
		return value_old;
	}


	private void parseAndPrint( Document templateu )
	{
		if( templateu != null )
			printDOMTree(templateu);
	}

	/**
	 * Prints a node and all its children
	 */
	private void printDOMTree( Node node )
	{
		int type = node.getNodeType();
		switch( type )
		{
			case Node.DOCUMENT_NODE:
			{
				System.err.println("<?xml version >");
				printDOMTree( ( (Document)node).getDocumentElement());
				break;
			}

			case Node.ELEMENT_NODE:
			{
				System.err.print("<");
				System.err.print( node.getNodeName() );
				NamedNodeMap attrs = node.getAttributes();
				for( int i=0; i< attrs.getLength(); i++ )
				{
					Node attr = attrs.item( i );
					System.err.print( " " + attr.getNodeName() +
								"=\"" + attr.getNodeValue() +
								"\"");
				}
				System.err.print(">");

				NodeList children = node.getChildNodes();
				if( children != null )
				{
					int len = children.getLength();
					for( int i=0; i<len; i++ )
						printDOMTree( children.item(i) );
				}
				break;
			}	

			case Node.ENTITY_REFERENCE_NODE:
			{
				System.err.print("&");
				System.err.print(node.getNodeName());
				System.err.print(";");
				break;
			}

			case Node.TEXT_NODE:
			{
				System.err.print( node.getNodeValue() );
				break;
			}
		}
		if( type == Node.ELEMENT_NODE )
		{
			System.err.print("</");
			System.err.print(node.getNodeName());
			System.err.print('>');
		}
	}

	public static void main( String arf[] )
	{
		XMLGenerator xg = new XMLGenerator();
		xg.generateVoucher( null );
	}
}
