/*
 * 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.client.controls.entityreference;

import com.google.gwt.user.client.Timer;
import com.queplix.core.client.app.vo.EntityReferenceData;
import com.queplix.core.client.app.vo.EntityReferenceDataRequest;
import com.queplix.core.client.app.vo.SortField;
import com.queplix.core.client.controls.QFormElementControllerImpl;
import com.queplix.core.client.controls.QFormElementModel;
import com.queplix.core.client.controls.QFormElementView;
import com.queplix.core.client.controls.grid.QGridModel;

import java.util.ArrayList;

class QEntityReferenceControllerImpl extends QFormElementControllerImpl
        implements QEntityReferenceController,
        QEntityReferenceViewImpl.EntityViewListener,
        QEntityReferenceModelImpl.EntityModelListener {

    private final static int DEFAULT_PAGE = 0;
    private final static int DEFAULT_PAGE_SIZE = 20;
    private final static boolean DEFAULT_DOCOUNT = false;

    private QEntityReferenceViewImpl view;
    private QEntityReferenceModelImpl model;

    private EntityReferenceDataRequest requestObject;

    private boolean buttonPressed = false;

    public QEntityReferenceControllerImpl(QEntityReferenceViewImpl view,
                                          QEntityReferenceModelImpl model) {
        this.view = view;
        this.model = model;
        view.setSearchListener(this);
        model.addEntityModelListener(this);
    }

    public void needMoreData(String filterString) {
        QGridModel gridModel = view.getGridModel();
        boolean doCount;
        int page;
        int pageSize;
        SortField order;
        if(gridModel != null) {
            doCount = gridModel.isCounterToggledOn();
            page = (int) gridModel.getCurrentPage();
            pageSize = gridModel.getPageSize();
            order = gridModel.getSortField();
        } else {
            doCount = DEFAULT_DOCOUNT;
            page = DEFAULT_PAGE;
            pageSize = DEFAULT_PAGE_SIZE;
            order = null;
        }
        sendRequest(filterString, page, pageSize, doCount, order);
    }

    public void searchButtonClicked(String filterString) {
        buttonPressed = true;
        model.setCanShowDialogOnDataCome(true);
        needMoreData(filterString);
    }

    public void searchTabOut(final String filterString) {
        model.getEntityReferenceData().setSelectedFilter(filterString);
        if(!filterString.equalsIgnoreCase("")) {
            new Timer() {
                public void run() {
                    int mode = view.getViewMode();
                    //send request if control in edit mode. is used, because it can be "clear" button pressed and tab out triggered
                    if((mode == QFormElementView.MODE_EDIT
                            || mode == QFormElementView.MODE_SEARCH
                            || mode == QFormElementView.MODE_NEW)
                            && !buttonPressed) {
                        model.setCanShowDialogOnDataCome(false);
                        sendRequest(filterString);
                    }
                }
            }.schedule(100);
        }
    }

    private void sendRequest(String filterString) {
        sendRequest(filterString, DEFAULT_PAGE, DEFAULT_PAGE_SIZE,
                DEFAULT_DOCOUNT, null);
    }

    private void sendRequest(String filterString, long page,
                             int prefferedLenght, boolean counterToggledOn,
                             SortField fieldToSort) {
        if(controlEventsListener != null) {
            if(requestObject == null) {
                requestObject = new EntityReferenceDataRequest(
                        model.getMeta().getFieldID(),
                        filterString,
                        model.getEntityReferenceData().getSelectedRowID(),
                        model.getReferencedEntityName(),
                        page, prefferedLenght, counterToggledOn, fieldToSort,
                        new ArrayList());
            } else {
                //no need to create it every time user click on button.
                // Even if next click rewrite filter value, user will get what his/her want.
                requestObject.init(filterString,
                        model.getEntityReferenceData().getSelectedRowID(),
                        page, prefferedLenght, counterToggledOn, fieldToSort);
            }
            controlEventsListener.needMoreData(requestObject);
        }
    }

    public void entitySelected(Long entityID, String filter) {
        EntityReferenceData entityReferenceData = model
                .getEntityReferenceData();
        Long rowID = entityReferenceData.getSelectedRowID();
        String oldFilter = entityReferenceData.getSelectedFilter();
        boolean notify = false;
        if (rowID != null) {//check if data is changing
            if (!rowID.equals(entityID)) {
                notify = true;
            }
        } else if (rowID != entityID) {
            notify = true;
        } else if (filter != null && !filter.equals(oldFilter)) {
            notify = true;
        }

        if (notify) {//change model's data and notify
            entityReferenceData.setSelectedRowID(entityID);
            entityReferenceData.setSelectedFilter(filter);
            model.fireSelectedEntityChanged();
        }
    }

    public void dialogWasHidden() {
        buttonPressed = false;
        int mode = view.getViewMode();
        if(mode == QFormElementView.MODE_EDIT
                || mode == QFormElementView.MODE_NEW) {
            EntityReferenceData entityReferenceData = model
                    .getEntityReferenceData();
            if(entityReferenceData.getSelectedRowID() == null) {
                entityReferenceData.setSelectedFilter("");
                model.fireSelectedEntityChanged();
            }
        }
    }

    public void onResolveEvent(boolean isStarted) {
        Events.ENTITY_REFERANCE_RESOLVE_EVENT.setData(Boolean.valueOf(
                isStarted));
        getEventSource().fireEvent(Events.ENTITY_REFERANCE_RESOLVE_EVENT);
    }

    public void modelMetaChanged() {
    }

    public void selectedEntityChanged() {
        String controlId = model.getBaseMeta().getFieldID();
        controlEventsListener.controlDataChanged(controlId);
    }

    public void onDemandDataCome() {
    }

    public QFormElementModel getModel() {
        return this.model;
    }

    public QFormElementView getView() {
        return this.view;
    }
}