/*
 * 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.common.ui.subsetselect;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.queplix.core.client.app.vo.SubsetItemMeta;
import com.queplix.core.client.common.ui.resizable.Resizable;
import com.queplix.core.client.common.ui.resizable.ResizableScrollPanel;
import com.queplix.core.client.i18n.I18N;

/**
 * Subset selector with checkboxes as selecting controls.
 *
 * @author Sultan Tezadov
 * @since 17 Nov 2006
 */
public class CheckboxSubsetSelect extends AbstractSubsetSelect
        implements ClickListener, Resizable {
    private static final String NULL_ITEM_TEXT = "NULL";

    private HorizontalPanel buttonsPanel;
    private VerticalPanel panel;
    private ResizableScrollPanel scrollPanel;
    private CheckBox[] checkboxes;
    private Button selectAll;
    private Button clearAll;
    private Button invert;
    private boolean needNull = true;
    private boolean isEnabled = true;

    public CheckboxSubsetSelect(boolean needNull) {
        this.needNull = needNull;
        panel = new VerticalPanel();
        scrollPanel = new ResizableScrollPanel(panel);
        initWidget(scrollPanel);
    }

    public CheckboxSubsetSelect() {
        this(false);
    }

    protected void createWidgets() {
        panel.clear();
        panel.add(getButtonsPanel());
        SubsetItemMeta[] items = getMeta().getItems();
        int n = items.length + (needNull ? 1:0);
        checkboxes = new CheckBox[n];
        for(int i = 0; i < n; i++) {
            String caption;
            if(needNull && i == n - 1) {
                caption = NULL_ITEM_TEXT;
            } else {
                caption = items[i].getCaption();
            }
            CheckBox checkbox = new CheckBox(caption);
            checkbox.setEnabled(isEnabled);
            checkboxes[i] = checkbox;
            panel.add(checkbox);
            checkbox.addClickListener(this);
        }
        panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
    }

    protected void populateWidgets() {
        SubsetItemMeta[] items = getMeta().getItems();
        int n = items.length;
        for(int i = 0; i < n; i++) {
            CheckBox checkbox = checkboxes[i];
            boolean value;
            if(needNull && i == n - 1) {
                value = getData().isNullSelected();
            } else {
                value = getData().isIDSelected(items[i].getId());
            }
            checkbox.setChecked(value);
        }
    }

    public void onClick(Widget sender) {
        if(sender instanceof CheckBox) {
            CheckBox checkbox = (CheckBox) sender;
            int i = panel.getWidgetIndex(sender);
            if(needNull && i == panel.getWidgetCount() - 1) {
                getData().setNullSelected(checkbox.isChecked());
            } else {
                long id = getMeta().getItems()[i - 1].getId();
                getData().setIDSelected(id, checkbox.isChecked());
            }
        } else if(sender == selectAll) {
            setAllCheckBoxes(Boolean.TRUE);
        } else if(sender == clearAll) {
            setAllCheckBoxes(Boolean.FALSE);
        } else if(sender == invert) {
            setAllCheckBoxes(null);
        }
    }

    public void setOffsetHeight(int height) {
        scrollPanel.setOffsetHeight(height);
    }

    public void setOffsetWidth(int width) {
        scrollPanel.setOffsetWidth(width);
    }

    private Widget getButtonsPanel() {
        if(buttonsPanel == null) {
            buttonsPanel = new HorizontalPanel();
            selectAll = new Button(I18N.getMessages().selectAll());
            selectAll.setEnabled(isEnabled);
            clearAll = new Button(I18N.getMessages().clearAll());
            clearAll.setEnabled(isEnabled);
            invert = new Button(I18N.getMessages().invert());
            invert.setEnabled(isEnabled);
            selectAll.addClickListener(this);
            clearAll.addClickListener(this);
            invert.addClickListener(this);
            buttonsPanel.add(selectAll);
            buttonsPanel.add(clearAll);
            buttonsPanel.add(invert);
        }
        return buttonsPanel;
    }

    private void setAllCheckBoxes(Boolean value) {
        boolean flag;
        for(int i = 0; i < checkboxes.length; i++) {
            if(value == null) {
                flag = !checkboxes[i].isChecked();
            } else {
                flag = value.booleanValue();
            }
            checkboxes[i].setChecked(flag);
            onClick(checkboxes[i]);
        }
    }

    public void setEnable(boolean enable) {
        isEnabled = enable;
        if(selectAll != null) {
            selectAll.setEnabled(enable);
        }
        if(clearAll != null) {
            clearAll.setEnabled(enable);
        }
        if(invert != null) {
            invert.setEnabled(enable);
        }
    }

}
