package org.objectweb.jonas.jtests.beans.ejbql;

import javax.ejb.FinderException;
import javax.ejb.EJBException;
import javax.ejb.EntityContext;
import javax.ejb.CreateException;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.rmi.RemoteException;

public abstract class CustomerBean implements javax.ejb.EntityBean {

    private CruiseHomeLocal cruiseHomeLocal = null;

    private CustomerHomeLocal customerHomeLocal = null;

    private CreditCardHomeLocal creditCardHomeLocal = null;

    private CreditCompanyHomeLocal creditCompanyHomeLocal = null;

    private AddressHomeLocal addressHomeLocal = null;

    public Integer ejbCreate(Integer id) throws javax.ejb.CreateException {
        this.setId(id);
        return null;
    }

    public void ejbPostCreate(Integer id) {
    }


    // business methods

    public Name getName() {
        Name name = new Name(getLastName(), getFirstName());
        return name;
    }
    public void setName(Name name) {
        setLastName(name.getLastName());
        setFirstName(name.getFirstName());
    }

    public void setAddress(String street, String city, String state, String zip)
        throws EJBException {

        AddressLocal addr = this.getHomeAddress();

        try {

            if (addr == null) {
                // Customer doesn't have an address yet. Create a new one.
                InitialContext cntx = new InitialContext();
                AddressHomeLocal addrHome = 
                    (AddressHomeLocal) cntx.lookup("java:comp/env/ejb/AddressHomeLocal");
                addr = addrHome.createAddress(street, city, state, zip);
                this.setHomeAddress(addr);
            } else {
                // Customer already has an address. Change its fields
                addr.setStreet(street);
                addr.setCity(city);
                addr.setState(state);
                addr.setZip(zip);
            }
        } catch (NamingException ne) {
            throw new EJBException(ne);
        } catch (CreateException ce) {
            throw new EJBException(ce);
        }
    }

    public void setAddress(AddressDO addrValue) throws CreateException, NamingException {
        String street = addrValue.getStreet();
        String city = addrValue.getCity();
        String state = addrValue.getState();
        String zip = addrValue.getZip();

        setAddress(street, city, state, zip);
    }


    public AddressDO getAddress() {

        AddressLocal addrLocal = this.getHomeAddress();
        if (addrLocal == null) {
            return null;
        }
        String street = addrLocal.getStreet();
        String city = addrLocal.getCity();
        String state = addrLocal.getState();
        String zip = addrLocal.getZip();
        AddressDO addrValue = new AddressDO(street, city, state, zip);
        return addrValue;
    }

    public void addPhoneNumber(String number, byte type) 
        throws NamingException, CreateException, RemoteException {
        InitialContext jndiEnc = new InitialContext();
        PhoneHomeLocal phoneHome = (PhoneHomeLocal) (jndiEnc.lookup("java:comp/env/ejb/PhoneHomeLocal"));

        PhoneLocal phone = phoneHome.create(number, type);
        Collection phoneNumbers = this.getPhoneNumbers();
        phoneNumbers.add(phone);
    }

    public void removePhoneNumber(byte typeToRemove) {

        Collection phoneNumbers = this.getPhoneNumbers();
        Iterator iterator = phoneNumbers.iterator();

        while (iterator.hasNext()) {
            PhoneLocal phone = (PhoneLocal) iterator.next();
            if (phone.getType() == typeToRemove) {
                phoneNumbers.remove(phone);
                break;
            }

        }
    }

    public void updatePhoneNumber(String number, byte typeToUpdate) {


        Collection phoneNumbers = this.getPhoneNumbers();
        Iterator iterator = phoneNumbers.iterator();
        while (iterator.hasNext()) {
            PhoneLocal phone = (PhoneLocal) iterator.next();
            if (phone.getType() == typeToUpdate) {
                phone.setNumber(number);
                break;
            }
        }
    }

    public Vector getPhoneList() {

        Vector vv = new Vector();
        Collection phoneNumbers = this.getPhoneNumbers();

        Iterator iterator = phoneNumbers.iterator();
        while (iterator.hasNext()) {
            PhoneLocal phone = (PhoneLocal) iterator.next();
            String ss = "Type=" + phone.getType() + "  Number=" + phone.getNumber();
            vv.add(ss);
        }

        return vv;
    }

    public Collection ejbHomeCallFindOnCruise(Integer cruiseId) throws FinderException {

        ArrayList customers_id = new ArrayList();
        CruiseLocal crloc = null;
        if (cruiseId != null) {
            crloc = cruiseHomeLocal.findByPrimaryKey(cruiseId);
        }
        Collection customers = customerHomeLocal.findOnCruise(crloc);
        Iterator customer = customers.iterator();
        while (customer.hasNext()) {
            CustomerLocal customer_local = (CustomerLocal) customer.next();
            customers_id.add(customer_local.getId());
        }
        return customers_id;
    }

    public Collection ejbHomeCallFindByAddressLocal(Integer add) throws FinderException {
        ArrayList customers_id = new ArrayList();
        AddressLocal addloc = null;
        if (add != null) {
            addloc = addressHomeLocal.findByPrimaryKey(add);
        }
        Collection customers = customerHomeLocal.findByAddressLocal(addloc);
        Iterator customer = customers.iterator();
        while (customer.hasNext()) {
            CustomerLocal customer_local = (CustomerLocal)customer.next();
            customers_id.add(customer_local.getId());
        }
        return customers_id;
    }

    public Collection ejbHomeCallFindByParameterIsNull(Integer cc) throws FinderException {
        ArrayList customers_id = new ArrayList();
        CreditCardLocal ccloc = null;
        if (cc != null) {
            ccloc = creditCardHomeLocal.findByPrimaryKey(cc);
        }
        Collection customers = customerHomeLocal.findByParameterIsNull(ccloc);
        Iterator customer = customers.iterator();
        while (customer.hasNext()) {
            CustomerLocal customer_local = (CustomerLocal)customer.next();
            customers_id.add(customer_local.getId());
        }
        return customers_id;
    }

    public  void setCreditCard(Date expCreditcard, String numbCreditcard, String nameCreditcard, String orgCreditcard , String nameCreditCompany, String streetAddress, String cityAddress, String stateAddress,  String zipAddress ) {

        // Create the CreditCompany, the Address and the CreditCard
        // Associate the Address to the CreditCompany, the CreditCompany to the
        // CreditCard and the CreditCard to the current customer
        try {
            CreditCardLocal creditcard = creditCardHomeLocal.create(expCreditcard, numbCreditcard, nameCreditcard, orgCreditcard);
            this.setCreditCard(creditcard);
            CreditCompanyLocal creditcompany = creditCompanyHomeLocal.create(nameCreditCompany);
            creditcard.setCreditCompany(creditcompany);
            AddressLocal address = addressHomeLocal.createAddress(streetAddress, cityAddress, stateAddress, zipAddress);
            creditcompany.setAddress(address);
        } catch (CreateException e) {
            System.out.println ("Probleme dans creation du CreditCompany/Address/CrediCard");
            e.printStackTrace(System.out);
        } 

    }

    // persistent relationships

    public abstract AddressLocal getHomeAddress();
    public abstract void setHomeAddress(AddressLocal address);

    public abstract CreditCardLocal getCreditCard();
    public abstract void setCreditCard(CreditCardLocal card);

    public abstract java.util.Collection getPhoneNumbers( );
    public abstract void setPhoneNumbers(java.util.Collection phones);

    // abstract accessor methods
    public abstract Integer getId();
    public abstract void setId(Integer id);
 
    public abstract String getLastName( );
    public abstract void setLastName(String lname);

    public abstract String getFirstName( );
    public abstract void setFirstName(String fname);

    public abstract boolean getHasGoodCredit();
    public abstract void setHasGoodCredit(boolean flag);

    // abstract ejbSelect() methods
    public abstract String ejbSelectAddrCity(Integer id) throws FinderException;
    public abstract String ejbSelectLastName(Integer id) throws FinderException;
    public abstract Set ejbSelectFirstName() throws FinderException;
    public abstract Collection ejbSelectDistinctFirstName() throws FinderException;
    public abstract AddressLocal ejbSelectAddr(Integer id) throws FinderException;
    public abstract Collection ejbSelectAllCreditCardAddr() throws FinderException;
    public abstract Collection ejbSelectRogerAddr() throws FinderException;
    public abstract long ejbSelectCountCreditCard() throws FinderException;
    public abstract Collection ejbSelectCreditCardNumbers() throws FinderException;
    public abstract long ejbSelectCountOfCustomersWithId1(Integer id) throws FinderException;
    public abstract long ejbSelectCountOfCustomersWithId2(int id) throws FinderException;
    public abstract long ejbSelectCountOfCustomersRingo() throws FinderException;

    //
	// Public Home method required to test the private ejbSelectXXXX method
	public String ejbHomeSelectAddrCity(Integer id) throws FinderException {
		return this.ejbSelectAddrCity(id);
	}
	public String ejbHomeSelectLastName(Integer id) throws FinderException {
		return this.ejbSelectLastName(id);
	}
	public Set ejbHomeSelectFirstName() throws FinderException {
		return this.ejbSelectFirstName();
	}
	public Collection ejbHomeSelectDistinctFirstName() throws FinderException {
		return this.ejbSelectDistinctFirstName();
	}
	public Integer ejbHomeSelectAddr(Integer id) throws FinderException {
        AddressLocal address = this.ejbSelectAddr(id);
		return address.getId();
	}
	public Collection ejbHomeSelectAllCreditCardAddr() throws FinderException {
        Collection addresses = this.ejbSelectAllCreditCardAddr();
        ArrayList addresses_id  = new ArrayList();
        Iterator iAddr = addresses.iterator();
        while (iAddr.hasNext()) {
            AddressLocal address = (AddressLocal) iAddr.next();
            addresses_id.add(address.getId());
        }
		return addresses_id;
	}
	public Collection ejbHomeSelectRogerAddr() throws FinderException {
        Collection addresses = this.ejbSelectRogerAddr();
        ArrayList addresses_id  = new ArrayList();
        Iterator iAddr = addresses.iterator();
        while (iAddr.hasNext()) {
            AddressLocal address = (AddressLocal) iAddr.next();
            addresses_id.add(address.getId());
        }
		return addresses_id;
	}
	public long ejbHomeGetCountCreditCard() throws FinderException {
		return this.ejbSelectCountCreditCard();
	}
	public Collection ejbHomeGetCreditCardNumbers() throws FinderException {
		return this.ejbSelectCreditCardNumbers();
	}
	public long ejbHomeGetCountCustomersWithId1(Integer id) throws FinderException {
		return this.ejbSelectCountOfCustomersWithId1(id);
	}
	public long ejbHomeGetCountCustomersWithId2(int id) throws FinderException {
		return this.ejbSelectCountOfCustomersWithId2(id);
	}
	public long ejbHomeGetCountCustomersRingo() throws FinderException {
		return this.ejbSelectCountOfCustomersRingo();
	}

    // standard call back methods

    public void setEntityContext(EntityContext ec) {
        try {
            InitialContext cntx = new InitialContext();
            cruiseHomeLocal = 
                (CruiseHomeLocal) cntx.lookup("java:comp/env/ejb/CruiseHomeLocal");
            customerHomeLocal = 
                (CustomerHomeLocal) cntx.lookup("java:comp/env/ejb/CustomerHomeLocal");
            creditCardHomeLocal = 
                (CreditCardHomeLocal) cntx.lookup("java:comp/env/ejb/CreditCardHomeLocal");
            creditCompanyHomeLocal = 
                (CreditCompanyHomeLocal) cntx.lookup("java:comp/env/ejb/CreditCompanyHomeLocal");
            addressHomeLocal = 
                (AddressHomeLocal) cntx.lookup("java:comp/env/ejb/AddressHomeLocal");
        } catch (Exception e) {
            throw new javax.ejb.EJBException(e);
        }
    }

    public void unsetEntityContext() { }
    public void ejbLoad() { }
    public void ejbStore() { }
    public void ejbActivate() { }
    public void ejbPassivate() { }
    public void ejbRemove() throws javax.ejb.RemoveException { }

}
