package Juno2.DataLoad;


import Juno2.*;


import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;


import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;



public class CustomerSAXParser implements XMLReader {


    private static final Attributes noattrs        = new AttributesImpl();
    protected ContentHandler        contenthandler = null;


    // Change these in derived class if you want to use some other markers
    protected static String customerMarker = "customer";
    protected static String accountMarker = "account";
    protected static String positionMarker = "position";


    public void parse(InputSource source) throws SAXException, IOException {


        if (!(source instanceof CustomerInputSource)) {
            throw new SAXException(
                "CustomerSAXParser can work only with source of type CustomerInputSource");
        }


        System.out.println("CustomerSAXParser proceeding with parsing");


        parse((CustomerInputSource) source);
    }


    public void parse(String systemId)
            throws SAXException, IOException {
        throw new SAXException(
            "CustomerSAXParser need a valid CustomerInputSource");
	}


    public void parse(CustomerInputSource source)
            throws SAXException, IOException {


        System.out.println("CustomerSAXParser entering parse");


        if (contenthandler == null) {
            return;
        }


        System.out.println("CustomerSAXParser parsing");


        try {


            contenthandler.startDocument();
        	contenthandler.startElement("", "", CmdConstants.DOCUMENT_ROOT_ELEMENT, noattrs);


			CustomerCVO ccvo;


			//// return one CustomerCVO - each CVO will become its own doc
			////while((ccvo = source.getCustomer()) != null) {
			
			ccvo = source.getCustomer(); // returns one CustomerCVO
			if(ccvo != null) 
            	parseCustomer(ccvo);
			////}


			contenthandler.endElement("", "", CmdConstants.DOCUMENT_ROOT_ELEMENT);
            contenthandler.endDocument();


        } catch (Exception ex) {
            throw new SAXException(ex);
        }
    }



    private void parseCustomer(CustomerCVO ccvo) throws SAXException {


		//// begin Customer
        contenthandler.startElement("", "", CmdConstants.CUSTOMER_ELEMENT, noattrs);


 		splatElement(CmdConstants.FIRSTNAME, ccvo.getFirstName());
		splatElement(CmdConstants.LASTNAME, ccvo.getLastName());
		splatElement(CmdConstants.CUSTOMERID, ccvo.getCustId());
		splatElement(CmdConstants.PASSWORD, ccvo.getPassword());



		HashMap acctList = ccvo.getAccountList();
		Iterator keys = acctList.keySet().iterator();


		while(keys.hasNext()){
			String accountId = (String)keys.next();
			parseAccount((AccountCVO)acctList.get(accountId));
		}


		//// end Customer
		contenthandler.endElement("", "", CmdConstants.CUSTOMER_ELEMENT);


	}


    private void parseAccount(AccountCVO acvo) throws SAXException {


		//// begin Account
        contenthandler.startElement("", "", CmdConstants.ACCOUNT_ELEMENT, noattrs);


 		splatElement(CmdConstants.CUSTOMERID, acvo.getCustId());
		splatElement(CmdConstants.ACCOUNTID, acvo.getAccountId());
		splatElement(CmdConstants.ACCOUNTBALANCE, Float.toString(acvo.getAccountBalance()));
		splatElement(CmdConstants.ACCOUNTDESCRIPTION, acvo.getAccountDescription());


		HashMap posList = acvo.getPositionList();
		Iterator keys = posList.keySet().iterator();


		while(keys.hasNext()){
			String symbol = (String)keys.next();
			parsePosition((PositionVO)posList.get(symbol));
		}


		//// end Account
		contenthandler.endElement("", "", CmdConstants.ACCOUNT_ELEMENT);


	}


    private void parsePosition(PositionVO pvo) throws SAXException {


		//// begin Position
        contenthandler.startElement("", "", CmdConstants.POSITION_ELEMENT, noattrs);


 		splatElement(CmdConstants.ACCOUNTID, pvo.getAccountId());
		splatElement(CmdConstants.SYMBOL, pvo.getSymbol());
		splatElement(CmdConstants.NUMBEROFSHARES, Integer.toString(pvo.getNumberOfShares()));
		splatElement(CmdConstants.PREVIOUSCLOSEPRICE, Float.toString(pvo.getPreviousClosePrice()));
		splatElement(CmdConstants.COSTBASIS, Float.toString(pvo.getCostBasis()));


		//// end Position
		contenthandler.endElement("", "", CmdConstants.POSITION_ELEMENT);


	}



	private void splatElement(String fieldName, String fieldValue)  throws SAXException {


		try {
			//// start element
			contenthandler.startElement("", "", fieldName, noattrs);


			//// element contents
			contenthandler.characters(fieldValue.toCharArray(), 0, fieldValue.length());


			//// end element
			contenthandler.endElement("", "", fieldName);
		} catch (SAXException ex) {
			throw new SAXException(ex);
		}
	}



    private EntityResolver er = null;
    private DTDHandler     dh = null;
    private ErrorHandler   eh = null;


    public void setContentHandler(ContentHandler handler) {
        contenthandler = handler;
    }


    public void setEntityResolver(EntityResolver e) {
        er = e;
    }


    public void setDTDHandler(DTDHandler d) {
		dh = d;
	}


	public void setErrorHandler(ErrorHandler e) {
		eh = e;
	}


	public ContentHandler getContentHandler() {
        return contenthandler;
    }


    public EntityResolver getEntityResolver() {
	    return er;
	}


	public DTDHandler getDTDHandler() {
		return dh;
	}


	public ErrorHandler getErrorHandler() {
		return eh;
	}



    /* Minimal support for features and properties.
    */
    public void setFeature(String feature, boolean b) {}


    public void setProperty(String property, Object o) {}


    public boolean getFeature(String feature) {
        return false;
    }


    public Object getProperty(String property) {
        return null;
    }
}



