/*
 * 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.ClickListener;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
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.StringUtil;
import com.queplix.core.client.common.ui.ButtonData;
import com.queplix.core.client.common.ui.IconButton;
import com.queplix.core.client.common.ui.resizable.Resizable;

/**
 * Subset selector with listboxes as selecting controls.
 *
 * @author Sultan Tezadov
 * @since 17 Nov 2006
 */
public class ListboxSubsetSelect extends AbstractSubsetSelect implements
        ClickListener,
        Resizable {
    private static String DEFAULT_WIDTH = "100px";
    private static String DEFAULT_HEIGHT = "200px";
    private static ButtonData LEFT = new ButtonData(null, "Deselect column",
            "subset/b_left.gif");
    private static ButtonData RIGHT = new ButtonData(null, "Select column",
            "subset/b_right.gif");
    private static ButtonData DOWN = new ButtonData(null, "Move down",
            "subset/b_down.gif");
    private static ButtonData UP = new ButtonData(null, "Move up",
            "subset/b_up.gif");

    private ListBox deselected;
    private ListBox selected;
    private HorizontalPanel panel;
    private IconButton left;
    private IconButton right;
    private IconButton up;
    private IconButton down;

    public ListboxSubsetSelect() {
        deselected = new ListBox();
        deselected.setMultipleSelect(true);
        selected = new ListBox();
        selected.setMultipleSelect(true);
        left = new IconButton(LEFT);
        right = new IconButton(RIGHT);
        up = new IconButton(UP);
        down = new IconButton(DOWN);
        panel = new HorizontalPanel();
        panel.add(deselected);
        VerticalPanel buttonPanel = new VerticalPanel();
        buttonPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        buttonPanel.add(right);
        buttonPanel.add(left);
        buttonPanel.add(up);
        buttonPanel.add(down);
        panel.add(buttonPanel);
        panel.setCellVerticalAlignment(buttonPanel,
                HasVerticalAlignment.ALIGN_MIDDLE);
        panel.add(selected);
        deselected.setWidth(DEFAULT_WIDTH);
        deselected.setHeight(DEFAULT_HEIGHT);
        selected.setWidth(DEFAULT_WIDTH);
        selected.setHeight(DEFAULT_HEIGHT);

        left.addClickListener(this);
        right.addClickListener(this);
        up.addClickListener(this);
        down.addClickListener(this);

        initWidget(panel);
    }

    protected void createWidgets() {
    } // all widgets already created

    protected void populateWidgets() {
        deselected.clear();
        selected.clear();
        // populate deselected
        SubsetItemMeta[] items = getMeta().getItems();
        for(int i = 0; i < items.length; i++) {
            long id = items[i].getId();
            if(!getData().isIDSelected(id)) {
                addItemToListBox(items[i], deselected);
            }
        }
        // populate selected in the specified order
        long[] selectedIDs = getData().getSelectedIDs();
        for(int i = 0; i < selectedIDs.length; i++) {
            SubsetItemMeta item = getMeta().getItemByID(selectedIDs[i]);
            addItemToListBox(item, selected);
        }
    }

    private void addItemToListBox(SubsetItemMeta item, ListBox listbox) {
        if(item != null) {
            String caption = item.getCaption();
            long id = item.getId();
            String strId = String.valueOf(id);
            listbox.addItem(caption, strId);
        }
    }

    public void onClick(Widget sender) {
        boolean changed = false;
        if(sender == left) {
            for(int i = 0; i < selected.getItemCount(); i++) {
                if(selected.isItemSelected(i)) {
                    String strId = selected.getValue(i);
                    long id = Long.parseLong(strId);
                    getData().setIDSelected(id, false);
                    changed = true;
                }
            }
            if(changed) {
                populateWidgets();
            }
        } else if(sender == right) {
            for(int i = 0; i < deselected.getItemCount(); i++) {
                if(deselected.isItemSelected(i)) {
                    String strId = deselected.getValue(i);
                    long id = Long.parseLong(strId);
                    getData().setIDSelected(id, true);
                    changed = true;
                }
            }
            if(changed) {
                populateWidgets();
            }
        } else if(sender == up) {
            int index = selected.getSelectedIndex();
            if(index > 0) {
                getData().swapItems(index - 1, index);
                populateWidgets();
                selected.setSelectedIndex(index - 1);
            }
        } else if(sender == down) {
            int index = selected.getSelectedIndex();
            if(index > -1 && index < (selected.getItemCount() - 1)) {
                getData().swapItems(index, index + 1);
                populateWidgets();
                selected.setSelectedIndex(index + 1);
            }
        }
    }

    public void setOffsetHeight(int height) {
        String heightSize = StringUtil.pixelToSize(height);
        deselected.setHeight(heightSize);
        selected.setHeight(heightSize);
        panel.setHeight(heightSize);
    }

    public void setOffsetWidth(int width) {
        int listWidth = (width - left.getOffsetWidth()) / 2;
        String listWidthSize = StringUtil.pixelToSize(listWidth);
        deselected.setWidth(listWidthSize);
        selected.setWidth(listWidthSize);
        panel.setWidth(StringUtil.pixelToSize(width));
    }

}
