package com.k_int.discover.lookup.location;

import com.k_int.discover.lookup.datamodel.LocationLookupResultDTO;
import com.opensymphony.xwork2.ActionSupport;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.k_int.discover.augmentation.geocode.BriefPlaceDetail;
import com.k_int.discover.augmentation.geocode.Geocoder;


/**
 * An action that given a postcode or place name looks it up in the CG
 * database and returns the lat / long for the location if found
 *
 * @author rpb rich@k-int.com
 * @version 1.0 18.01.11
 * 
 */
public class LookupLocation extends ActionSupport implements ServletRequestAware, ApplicationContextAware {
	private static final long serialVersionUID = 5872998885506200403L;
	private static Log log = LogFactory.getLog(LookupLocation.class);

    protected HttpServletRequest request;
    protected ApplicationContext ctx;
    protected SessionFactory factory;

    public void setServletRequest(HttpServletRequest request) { this.request = request; }
    public void setApplicationContext(ApplicationContext ctx) {	this.ctx = ctx; }
    public void setSessionFactory(SessionFactory factory) { this.factory = factory; }
    
    public Set<LocationLookupResultDTO> locationResults = new LinkedHashSet<LocationLookupResultDTO>();
    public Set<LocationLookupResultDTO> getLocationResults() { return this.locationResults; }
    
    @Override
    public String execute() {
        log.debug("LookupLocation::execute method called");

        String returnValue = "xml";
        
        String searchTerm = request.getParameter("q");
        log.debug("search term retrieved from request as : " + searchTerm);
        String queryFormat = request.getParameter("format");
        if ( queryFormat != null ) {
            if ( "json".equals(queryFormat.trim()) ) {
                returnValue = "json";
            } else if ( "xml".equals(queryFormat.trim()) ) {
                returnValue = "xml";
            }
        }
        
        if ( searchTerm != null && !"".equals(searchTerm.trim()) ) {

            searchTerm = searchTerm.trim();
            searchTerm = searchTerm.toUpperCase();
            if ( !searchTerm.startsWith("\"") ) 
                searchTerm = "\"" + searchTerm;
            if ( !searchTerm.endsWith("\"") )
                searchTerm = searchTerm + "\"";

           	List<BriefPlaceDetail> geoBriefDetails = Geocoder.getBriefDetails(searchTerm);
           	if (geoBriefDetails != null) {
           		for (BriefPlaceDetail geoBriefDetail : geoBriefDetails) {
                    LocationLookupResultDTO locationResult = new LocationLookupResultDTO();
                    locationResult.setName(geoBriefDetail.getFormattedAddress());
                    locationResult.setLat(geoBriefDetail.getLatitudeLongitude().getLatitude().doubleValue());
                    locationResult.setLng(geoBriefDetail.getLatitudeLongitude().getLongitude().doubleValue());
                    locationResults.add(locationResult);
           		}
           	}

            log.debug("Finished searching - got " + this.locationResults.size() + " results");

            request.setAttribute("locationResults", this.locationResults);

        } else {
            // No search term!
            log.error("LookupLocation called without a search term!");
        }
        return(returnValue);
    }
}
