/**
 * Copyright (c) 2004 Red Hat, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Component of: Red Hat Application Server
 * 
 * Initial Developers: Aizaz Ahmed
 *                     Vivek Lakshmanan
 *                     Andrew Overholt
 *                     Matthew Wringe
 *
 */

/*
 * ItemHelperBean.java
 * 
 * Created on Aug 16, 2004
 *
 */
package olstore.session.helper;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;
import java.math.BigDecimal;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import olstore.dto.ItemValue;
import olstore.dto.PictureValue;
import olstore.dto.PropertyValue;
import olstore.framework.EJBHomeFactory;

import org.apache.commons.beanutils.BeanUtils;

import olstore.entity.ItemLocal;
import olstore.entity.ItemLocalHome;
import olstore.entity.PictureLocalHome;
import olstore.entity.PropertyLocal;
import olstore.entity.PropertyLocalHome;
import olstore.entity.TypeLocal;
import olstore.entity.TypeLocalHome;
import olstore.entity.UserLocal;
import olstore.entity.UserLocalHome;

/**
 * @ejb.bean name="ItemHelper"
 *	type="Stateless" 
 *  view-type="local"
 *  local-jndi-name="ItemHelperLocal_L"
 * 
 * @ejb.ejb-ref
 *  ejb-name="Type"
 *  view-type="local"
 * 
 * @ejb.ejb-ref
 *  ejb-name="Item"
 *  view-type="local"
 * 
 * @ejb.ejb-ref
 *  ejb-name="Property"
 *  view-type="local"
 * 
 * @ejb.ejb-ref
 *  ejb-name="Picture"
 *  view-type="local"
 * 
 * @ejb.transaction
 *  type="Required"
 * 
 *--
 * change this --> /transaction-type=/"Container"
 * 
 * This is needed for JOnAS.
 * If you are not using JOnAS you can safely remove the tags below.
 * @jonas.bean ejb-name="ItemHelper"
 * jndi-name="ItemHelperLocal"
 * 
 *--
 **/

public abstract class ItemHelperBean implements SessionBean, ItemHelper {
    SessionContext ejbContext;                                                                          
    
    // ------------------------------------------------------------------                               
    // SessionBean implementation                                                                       
    // ------------------------------------------------------------------                               
    
    
    public void setSessionContext(SessionContext ctx) {                                                 
        ejbContext = ctx;                                                                               
    }                                                                                                   
    
    
    public void ejbRemove() {                                                                           
    }                                                                                                   
    
    
    public void ejbCreate() throws CreateException {
    }
    
    public void ejbPassivate() {
    }
    
    public void ejbActivate() {
    }
    
    // ------------------------------------------------------------------
    // ItemHelper implementation
    // ------------------------------------------------------------------
    
    /**
     * A convenience method to help create new items. The fields
     * {@param name}, {@param name}, {@param shortDescr}, {@param type}  
     * are mandatory.
     * 
     * @ejb.interface-method
     * 
     */
    
    public olstore.entity.ItemLocal createItem ( String name,
            String price,
            String shortDesc,
            String longDesc,
            String type
    ) throws NamingException, CreateException {
        
        Context initialContext = new InitialContext ();
        ItemLocal item = null;
        EJBHomeFactory factory = EJBHomeFactory.getInstance();
        
        try {
            ItemLocalHome itemHome = (ItemLocalHome)factory.getLocalHome (EJBHomeFactory.ITEM);
            item = itemHome.create ( name, new BigDecimal( price ));
            item.setShortDesc ( shortDesc );
            if ( longDesc == null ) {
                item.setLongDesc ( "" );
            } else {
                item.setLongDesc ( longDesc );
            }
        } catch (NamingException e){
            System.out.println("1: " + e.getMessage());
            e.printStackTrace();
        }
        
        //Try and get the appropriate type
        try {
            TypeLocalHome typeHome = (TypeLocalHome) factory.getLocalHome(EJBHomeFactory.TYPE);
            TypeLocal typeObj = typeHome.findByName ( type );
            item.setTypeId ( typeObj );
        } catch (NamingException e) {
            System.out.println("2: " + e.getMessage());
            e.printStackTrace();
        } catch ( Exception e ) {
            throw new EJBException ( "Could not register type: "
                    + type + " to new item", e );
        }
        
        //Set default mainpage and special properties
        item.setMainPage (java.lang.Boolean.FALSE);
        item.setSpecialOffer (java.lang.Boolean.FALSE);
        
        return item;
    }
    
    /**
     * This method returns the first picture with priority 0.
     * Will return a random picture if there is none with prioriy 0
     * 
     * @ejb.interface-method
     * 
     */
    public olstore.entity.PictureLocal getPicture ( olstore.entity.ItemLocal item ) {
        olstore.entity.PictureLocal pic = null ;
        Collection pics = item.getPictures ();
        Iterator it = pics.iterator();
        while ( it.hasNext() ) {
            pic = (olstore.entity.PictureLocal) it.next ();
            if ( pic.getPriority() == 0 ) {
                break;
            }
        }
        
        return pic ;
    }
    
    /**
     * 
     * @param itemId
     * @return
     * @throws Exception
     * 
     * @ejb.interface-method
     */
    
    public PictureValue getPicture ( String itemId ) throws Exception {
        EJBHomeFactory factory=EJBHomeFactory.getInstance();
        ItemLocalHome home = (ItemLocalHome)factory.getLocalHome (EJBHomeFactory.ITEM);
        olstore.entity.ItemLocal itemLocal = home.findByPrimaryKey ( new Integer ( itemId ) );
        
        olstore.entity.PictureLocal picLocal =  getPicture ( itemLocal );
        PictureValue picVal = new PictureValue() ;
        if ( picLocal != null ) {
            BeanUtils.copyProperties ( picVal, picLocal );
        }
        
        return picVal;
    }
    
    
    
    /**
     * This method will return an array of PropertyValues that indicate
     * the default properties associated with the specified type
     * 
     * @ejb.interface-method
     */
    public Vector getPropertiesForType ( String type ) throws Exception {
        
        //Load up the default properties for specified type
        EJBHomeFactory factory = EJBHomeFactory.getInstance();
        TypeLocalHome typeHome = (TypeLocalHome) factory.getLocalHome ( EJBHomeFactory.TYPE );
        TypeLocal typeLocal = typeHome.findByName ( type );
        Collection props = typeLocal.getProperties();
        Iterator it = props.iterator() ;
        Vector propValueArr = new Vector() ;
        while ( it.hasNext() ) {
            PropertyLocal prop = (PropertyLocal) it.next() ;
            PropertyValue propValue = new PropertyValue();
            BeanUtils.copyProperties ( propValue, prop );
            propValueArr.add ( propValue );
        }
        //Assume types have at least one property
        return propValueArr;
    }
    
    /**
     * 
     * @param itemId
     * @return
     * @throws Exception
     * 
     * @ejb.interface-method
     */
    
    public ItemValue getItemValueForId ( String itemId ) throws Exception {
        
        EJBHomeFactory factory = EJBHomeFactory.getInstance();
        ItemLocalHome itemHome = (ItemLocalHome) factory.getLocalHome ( EJBHomeFactory.ITEM );
        olstore.entity.ItemLocal item = itemHome.findByPrimaryKey ( new Integer ( itemId ) );
        ItemValue itemVal = convertToDTO ( item );
        return itemVal;
    }
    
    /**
     * 
     * @param itemVal
     * @throws Exception
     * 
     * @ejb.interface-method
     */
    
    public void saveItem ( ItemValue itemVal ) throws Exception {
        
        //determine if it already exists
        EJBHomeFactory factory = EJBHomeFactory.getInstance();
        ItemLocalHome itemHome = (ItemLocalHome) factory.getLocalHome ( EJBHomeFactory.ITEM );
        olstore.entity.ItemLocal item = null;
        
        Integer itemId = itemVal.getItemId();
        if ( itemId != null && itemId.intValue () != 0 ) {
            item = itemHome.findByPrimaryKey ( itemId );
        } else {
            item = itemHome.create ( itemVal.getName(), itemVal.getPrice() );
        }
        
        updateItem ( item, itemVal );
    }
    
    /**
     * 
     * @param item
     * @param itemVal
     * @throws Exception
     * 
     */
    
    private void updateItem ( olstore.entity.ItemLocal item , ItemValue itemVal ) throws Exception {
        
        //Get instance vars we will need
        EJBHomeFactory factory = EJBHomeFactory.getInstance();
        PictureLocalHome picHome = (PictureLocalHome) factory.getLocalHome ( EJBHomeFactory.PIC );
        TypeLocalHome typeHome = (TypeLocalHome) factory.getLocalHome ( EJBHomeFactory.TYPE );
        PropertyLocalHome propHome = (PropertyLocalHome) factory.getLocalHome ( EJBHomeFactory.PROP );
        
        
        //Load up the values ( can't use BeanUtils here without a way to filter out
        //certain fields (collections, PK, etc)
        item.setName ( itemVal.getName() );
        item.setPrice ( itemVal.getPrice () );
        item.setShortDesc ( itemVal.getShortDesc() );
        item.setLongDesc ( itemVal.getLongDesc() );
        item.setMainPage ( itemVal.getMainPage () );
        item.setSpecialOffer ( itemVal.getSpecialOffer () );
        
        item.setTypeId ( typeHome.findByName ( itemVal.getTypeId() ) );
        
        
        //Clear any existing Properties
        Collection props = item.getProperties();
        Iterator propIt = props.iterator();
        while ( propIt.hasNext() ) {
            PropertyLocal prop = (PropertyLocal) propIt.next();
            propIt.remove();
            prop.remove();
        }
        
        //Load new Properties
        Collection newProps = itemVal.getProperties();
        Iterator newPropIt = newProps.iterator();
        while ( newPropIt.hasNext() ) {
            PropertyValue newProp = (PropertyValue) newPropIt.next();
            PropertyLocal newPropLocal = propHome.create (
                    newProp.getName(), newProp.getValue() );
            props.add ( newPropLocal );
        }
        
        //Clear any existing Pictures
        Collection pics = item.getPictures();
        Iterator picIt = pics.iterator();
        while ( picIt.hasNext() ) {
            olstore.entity.PictureLocal pic = (olstore.entity.PictureLocal) picIt.next();
            picIt.remove();
            pic.remove();
        }
        
        //Load new Pictures
        Collection newPics = itemVal.getPictures();
        Iterator newPicIt = newPics.iterator();
        while ( newPicIt.hasNext() ) {
            PictureValue newPic = (PictureValue) newPicIt.next();
            olstore.entity.PictureLocal newPicLocal = picHome.create (
                    newPic.getLocation(),
                    newPic.getText(),
                    newPic.getPriority() );
            pics.add ( newPicLocal );
        }
        
        
        
    }
    
    /**
     * @ejb.interface-method
     */
    public ItemValue convertToDTO ( olstore.entity.ItemLocal item ) throws Exception {
        ItemValue itemVal = new ItemValue();
        BeanUtils.copyProperties ( itemVal, item );
        
        //Special Conversions
        itemVal.setTypeId ( item.getTypeId().getName() );
        
        //properties
        Vector newProps = new Vector();
        Collection oldProps = item.getProperties();
        Iterator it = oldProps.iterator();
        while ( it.hasNext() ) {
            PropertyLocal prop = (PropertyLocal)it.next();
            PropertyValue propVal = new PropertyValue();
            BeanUtils.copyProperties ( propVal, prop );
            newProps.add ( propVal );
        }
        itemVal.setProperties ( newProps );
        
        //pictures
        Vector newPics = new Vector();
        Collection oldPics = item.getPictures();
        Iterator pics  = oldPics.iterator();
        while ( pics.hasNext() ) {
            olstore.entity.PictureLocal pic = (olstore.entity.PictureLocal)pics.next();
            PictureValue picVal = new PictureValue();
            BeanUtils.copyProperties ( picVal, pic );
            newPics.add ( picVal );
        }
        itemVal.setPictures ( newPics );
        
        return itemVal;
    }
    
    /**
     * 
     * @param itemId
     * @param username
     * @throws Exception
     * 
     * @ejb.interface-method
     */
    
    public void markItemAsInteresting ( String itemId, String username ) throws Exception {
        EJBHomeFactory factory=EJBHomeFactory.getInstance();
        ItemLocalHome home = (ItemLocalHome)factory.getLocalHome (EJBHomeFactory.ITEM);
        UserLocalHome userHome = (UserLocalHome)factory.getLocalHome(EJBHomeFactory.USER);
        
        olstore.entity.ItemLocal itemLocal = home.findByPrimaryKey ( new Integer ( itemId ) );
        UserLocal user = userHome.findByUsername ( username );
        
        Collection purchased = user.getPurchased ();
        if ( ! purchased.contains ( itemLocal ) ) {
            purchased.add ( itemLocal );
            user.setPurchased ( purchased );
        }
    }
    
}
