/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */
package com.queplix.core.server.app.rpc;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.queplix.core.client.app.rpc.DataService;
import com.queplix.core.client.app.rpc.RPCException;
import com.queplix.core.client.app.vo.UnreadMessagesResponse;
import com.queplix.core.client.app.vo.AccumulatedEntitiesRequestObject;
import com.queplix.core.client.app.vo.AccumulatedEntityDataResponse;
import com.queplix.core.client.app.vo.AdhocDeleteReportRequest;
import com.queplix.core.client.app.vo.AdhocPrintRequestObject;
import com.queplix.core.client.app.vo.AdhocSearchGridRecordsRequest;
import com.queplix.core.client.app.vo.BaseGridRequest;
import com.queplix.core.client.app.vo.ChartFieldDataRequest;
import com.queplix.core.client.app.vo.ClearEntityRequestObject;
import com.queplix.core.client.app.vo.CustomizeGridRequestObject;
import com.queplix.core.client.app.vo.EmailComposeRequestObject;
import com.queplix.core.client.app.vo.EmailComposeResponseObject;
import com.queplix.core.client.app.vo.EntityDataResponseObject;
import com.queplix.core.client.app.vo.EntityDeleteRequestObject;
import com.queplix.core.client.app.vo.EntityIDRequestObject;
import com.queplix.core.client.app.vo.EntityUpdateRequestObject;
import com.queplix.core.client.app.vo.EntityUpdateResponseObject;
import com.queplix.core.client.app.vo.FieldDataRequest;
import com.queplix.core.client.app.vo.FieldOnDemandData;
import com.queplix.core.client.app.vo.FieldType;
import com.queplix.core.client.app.vo.FormatDataRequestObject;
import com.queplix.core.client.app.vo.FormatDataResponseObject;
import com.queplix.core.client.app.vo.LoadReportResponseObject;
import com.queplix.core.client.app.vo.MetaData;
import com.queplix.core.client.app.vo.MessageReadFlagRequest;
import com.queplix.core.client.app.vo.MoreDataResponseObject;
import com.queplix.core.client.app.vo.NewEntityRequestObject;
import com.queplix.core.client.app.vo.ParseDateRequestObject;
import com.queplix.core.client.app.vo.ParseDateResponseObject;
import com.queplix.core.client.app.vo.PortalCssRequest;
import com.queplix.core.client.app.vo.PortalCssResponse;
import com.queplix.core.client.app.vo.PrintFormRequestObject;
import com.queplix.core.client.app.vo.PrintGridRequestObject;
import com.queplix.core.client.app.vo.SaveAdhocReportRequestObject;
import com.queplix.core.client.app.vo.SavedSearchDeleteRequestObject;
import com.queplix.core.client.app.vo.SavedSearchObject;
import com.queplix.core.client.app.vo.SearchGridRecordsResponseObject;
import com.queplix.core.integrator.IntegratorGetRecords;
import com.queplix.core.integrator.IntegratorReports;
import com.queplix.core.integrator.UserSettingsManager;
import com.queplix.core.modules.config.jxb.portal.PortalConfig;
import com.queplix.core.utils.www.GWTHelper;
import com.queplix.core.utils.www.ServletHelper;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

/**
 * Data Service implementation.
 *
 * @author Sultan Tezadov
 * @since 17 Oct 2006
 */
public class DataServiceImpl extends RemoteServiceServlet
        implements DataService {

    public DataServiceImpl() {
    }

    public SearchGridRecordsResponseObject searchWithMultipleFormConstraints(
            AccumulatedEntitiesRequestObject multipleFormSearchRequest)
            throws RPCException {
        SearchGridRecordsResponseObject returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords
                    .searchWithMultipleFormConstraints(
                            multipleFormSearchRequest, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public AccumulatedEntityDataResponse getEntityData(
            EntityIDRequestObject entityDataRequest) throws RPCException {
        AccumulatedEntityDataResponse returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.getEntityData(entityDataRequest,
                    httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public AccumulatedEntityDataResponse getLockForEditRecord(
            EntityIDRequestObject entityDataRequest) throws RPCException {
        AccumulatedEntityDataResponse returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.getLockForEditRecord(
                    entityDataRequest, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public AccumulatedEntityDataResponse unlockAfterEditRecord(
            EntityIDRequestObject entityDataRequest) throws RPCException {
        AccumulatedEntityDataResponse response = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            response = IntegratorGetRecords.unlockAfterEditRecord(
                    entityDataRequest, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return response;
    }

    public EntityUpdateResponseObject updateRecord(
            EntityUpdateRequestObject updateRequest) throws RPCException {
        EntityUpdateResponseObject returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.updateRecord(updateRequest,
                    httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public void deleteRecord(EntityDeleteRequestObject request)
            throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorGetRecords.deleteRecord(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public EntityUpdateResponseObject insertRecord(
            EntityUpdateRequestObject updateRequest) throws RPCException {
        EntityUpdateResponseObject returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.insertRecord(updateRequest,
                    httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public EntityDataResponseObject createEntity(NewEntityRequestObject request)
            throws RPCException {
        EntityDataResponseObject returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.createEntity(request,
                    httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    // new {{{
    private static final String INIT_PARAM_CHART_SERVLET_PATH_PATTERN
            = "ChartServletPathPattern";
    private static String CHART_SERVLET_PATH_PATTERN;
    public void init(ServletConfig config) throws ServletException {

        super.init(config);

        // Gets default chart's settings
        CHART_SERVLET_PATH_PATTERN = ServletHelper.getInitParamAsString(
                config, INIT_PARAM_CHART_SERVLET_PATH_PATTERN);
    }
    // new }}}
    public MoreDataResponseObject getMoreData(FieldDataRequest request)
            throws RPCException {
        MoreDataResponseObject returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            
            // TODO review this code later
            // Perhaps inroduce ModeDataProvider

            if (request.getRequestType() == FieldType.CHART) {
                FieldOnDemandData onDemandData = ChartServiceImpl.buildChart(
                        (ChartFieldDataRequest)request, httpRequest,
                                CHART_SERVLET_PATH_PATTERN);
                returnValue = new MoreDataResponseObject(onDemandData);
            } else {
                returnValue = IntegratorGetRecords.getMoreData(request,
                        httpRequest);
            }
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public void printForm(PrintFormRequestObject printRequest)
            throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorGetRecords.printForm(printRequest, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public void printGrid(PrintGridRequestObject printRequest)
            throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorGetRecords.printGrid(printRequest, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public void saveSearch(SavedSearchObject search) throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorGetRecords.saveSearch(search, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public SavedSearchObject[] loadSavedSearches() throws RPCException {
        SavedSearchObject[] returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.loadSavedSearches(
                    getThreadLocalRequest());
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public void deleteSavedSearch(SavedSearchDeleteRequestObject request)
            throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorGetRecords.deleteSavedSearch(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public ParseDateResponseObject parseDate(
            ParseDateRequestObject parseRequest) throws RPCException {
        ParseDateResponseObject returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.parseDate(parseRequest,
                    httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public FormatDataResponseObject formatDate(FormatDataRequestObject request)
            throws RPCException {
        HttpServletRequest httpRequest = getThreadLocalRequest();
        FormatDataResponseObject returnValue = IntegratorGetRecords.formatDate(
                request, httpRequest);
        try {
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.formatDate(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public void customizeGrid(CustomizeGridRequestObject request)
            throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorGetRecords.customizeGrid(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public SearchGridRecordsResponseObject customEntitiesFieldsSearch(
            AdhocSearchGridRecordsRequest request) throws RPCException {
        SearchGridRecordsResponseObject response = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            response = IntegratorReports.customEntitiesFieldsSearch(request,
                    httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return response;
    }

    public void customEntitiesFieldsReport(AdhocPrintRequestObject request)
            throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorReports.printCustomReport(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public void saveReport(SaveAdhocReportRequestObject request)
            throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorReports.saveReport(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public SearchGridRecordsResponseObject loadReports(BaseGridRequest request)
            throws RPCException {
        SearchGridRecordsResponseObject response = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            response = IntegratorReports.loadReportList(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return response;
    }

    public LoadReportResponseObject loadReport(EntityIDRequestObject request)
            throws RPCException {
        LoadReportResponseObject response = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            response = IntegratorReports.loadReport(request, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return response;
    }

    public SearchGridRecordsResponseObject deleteReport(
            AdhocDeleteReportRequest reportId) throws RPCException {
        SearchGridRecordsResponseObject response = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            response = IntegratorReports.deleteReport(reportId, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return response;
    }

    public void saveSettings(MetaData metaData) throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            UserSettingsManager.saveUserUISettings(metaData, httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
    }
    
    public void setMessageReadFlag(MessageReadFlagRequest request) 
                                                          throws RPCException {
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            IntegratorGetRecords.setMessageReadFlag(request.getMessageId(), 
                request.isReadFlag(), getServletContext());
        } catch(Exception e) {
            GWTHelper.throwSerializableException(e);
        }
    }

    public AccumulatedEntityDataResponse clearEntity(
            ClearEntityRequestObject request) throws RPCException {
        AccumulatedEntityDataResponse returnValue = null;
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            returnValue = IntegratorGetRecords.clearEntity(request,
                    httpRequest);
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return returnValue;
    }

    public EmailComposeResponseObject sendEmail(
            EmailComposeRequestObject request) throws RPCException {
        EmailComposeResponseObject result = new EmailComposeResponseObject();
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            result.setResult(IntegratorGetRecords.sendEmail(request,
                    httpRequest));
        } catch (Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return result;
    }
    
    public PortalCssResponse retrievePortalCss(PortalCssRequest request) 
       throws RPCException {
        PortalCssResponse result = new PortalCssResponse();
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            PortalConfig portal = IntegratorGetRecords.getPortalConfig(
                request.getPortalType(), getServletContext());
            if (portal != null && portal.getCss() != null) {
                result.setCssUrl(portal.getCss().getFilename());
            }
        } catch(Throwable e) {
            GWTHelper.throwSerializableException(e);
        }
        return result;
    }

    public UnreadMessagesResponse hasUnreadMessages() throws RPCException {
        UnreadMessagesResponse result = new UnreadMessagesResponse();
        try {
            HttpServletRequest httpRequest = getThreadLocalRequest();
            GWTHelper.checkLogin(httpRequest);
            result.setHasUnreadMessages(IntegratorGetRecords.
                hasUnreadMessages(httpRequest, getServletContext()));
        } catch(Exception e) {
            GWTHelper.throwSerializableException(e);
        }
        return result;
    }
}
