/*
 * 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;

import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.Widget;
import com.queplix.core.client.app.vo.FormButtonMeta;
import com.queplix.core.client.common.ui.ButtonData;
import com.queplix.core.client.common.ui.LinkIconButton;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * QButton.
 *
 * @author Alexander Epifanov, Vasily Mikhailitchenko
 * @since 17 Nov 2006
 */
public class QButton extends QFormLayoutElement implements SourcesClickEvents {
    public static final int BUTTON_TYPE_BUTTON
            = FormButtonMeta.BUTTON_TYPE_BUTTON;
    public static final int BUTTON_TYPE_LINK = FormButtonMeta.BUTTON_TYPE_LINK;

    public static final int TYPE_COMMON = 0;
    private String caption;
    private String tooltip;
    private FocusPanel mainPanel;
    private HorizontalPanel buttonPanel;
    private HTML label;
    private boolean isEnabled = true;
    private int currentType = TYPE_COMMON;
    private final List clickListeners = new ArrayList();
    private int buttonType = BUTTON_TYPE_BUTTON;
    private String icon;
    private String captionStyle;

    private static final int REPORT_BUTTON_WIDTH = 17;
    private static final int COLUMN_SEPARATOR_WIDTH = 3;
    private MouseListener mouseListener;

    public static final class CustomButtonEventData {

        private final String buttonId;

        public CustomButtonEventData(String buttonId) {
            this.buttonId = buttonId;
        }

        public String getButtonId() {
            return buttonId;
        }

    }

    public QButton(String caption) {
        this(caption, QFormElement.HORIZONTAL);
    }

    public QButton(String caption, String tooltip) {
        this(caption, tooltip, QFormElement.HORIZONTAL, true);
    }

    public QButton(String caption, int layout) {
        this(caption, layout, BUTTON_TYPE_BUTTON, null, null, true);
    }

    public QButton(String caption, int layout, int buttonType, String icon,
                   String captionStyle, boolean isWidthFixed) {
        this.caption = caption;
        this.buttonType = buttonType;
        this.icon = icon;
        this.captionStyle = captionStyle;
        initializeBaseUI(layout, isWidthFixed);
    }

    public QButton(String caption, ClickListener clickListener, int layout) {
        this(caption, layout);
        addClickListener(clickListener);
    }

    public QButton(String caption, String tooltip, int layout,
                   boolean isWidthFixed) {
        this(caption, layout, BUTTON_TYPE_BUTTON, null, null, isWidthFixed);
        setTooltip(tooltip);
    }

    public QButton(String caption, ClickListener clickListener, String tooltip,
                   int layout) {
        this(caption, clickListener, layout);
        setTooltip(tooltip);
    }

    public void initializeBaseUI(int layout, boolean isWidthFixed) {
        super.initializeBaseUI(layout);
        ClickListener clickListener = new ClickListener() {
            public void onClick(Widget sender) {
                if(isEnabled) {
                    for(Iterator it = clickListeners.iterator(); it.hasNext();)
                    {
                        ClickListener listener = (ClickListener) it.next();
                        listener.onClick(QButton.this);
                    }
                }
            }
        };
        if(buttonType == BUTTON_TYPE_LINK) {
            initForLinkType(clickListener);
        } else {
            initForButtonType(clickListener, isWidthFixed);
        }

        initPanel();
    }

    public void setCaptionOffsetWidth(int captionOffsetWidth) {
        if(!isVerticalLayout()) {
            if(captionOffsetWidth != 0) {
                captionOffsetWidth = captionOffsetWidth + REPORT_BUTTON_WIDTH;
            } else {
                captionOffsetWidth = captionOffsetWidth
                        + COLUMN_SEPARATOR_WIDTH;
            }
        }
        super.setCaptionOffsetWidth(captionOffsetWidth);
    }

    private void initForButtonType(ClickListener clickListener,
                                   boolean isWidthFixed) {
        if(isVerticalLayout()) {
            setCaptionOffsetWidth(0);
        }
        mainPanel = new FocusPanel();
        buttonPanel = new HorizontalPanel();

        Label leftSide = new Label(" ");
        leftSide.setStyleName("button_leftSide");

        label = new HTML(this.caption);
        label.setWordWrap(false);
        label.setStyleName("button_middle");
        if(isWidthFixed) {
            label.addStyleName("button_width");
        }

        Label rightSide = new Label(" ");
        rightSide.setStyleName("button_rightSide");

        buttonPanel.add(leftSide);
        buttonPanel.add(label);
        buttonPanel.add(rightSide);

        mainPanel.setWidget(buttonPanel);
        mainPanel.addClickListener(clickListener);
        initMouseListener();
        mainPanel.addMouseListener(mouseListener);
        buttonPanel.setStyleName("button_Enabled");
        addToPanel(mainPanel);
    }

    private void initMouseListener() {
        mouseListener = new MouseListenerAdapter() {
            public void onMouseEnter(Widget sender) {
                if(isEnabled) {
                    buttonPanel.addStyleName("button_Highlighted");
                }
            }

            public void onMouseLeave(Widget sender) {
                buttonPanel.removeStyleName("button_Highlighted");
            }
        };
    }

    private void initForLinkType(ClickListener clickListener) {
        ButtonData buttonData = new ButtonData(caption, null, icon);
        buttonData.setCaptionStyle(captionStyle);
        buttonData.setCaptionHoverStyle(captionStyle + "_hover");

        LinkIconButton button = new LinkIconButton(buttonData);
        button.addClickListener(clickListener);
        addToPanel(button);
    }

    public void addClickListener(ClickListener listener) {
        clickListeners.add(listener);
    }

    public void removeClickListener(ClickListener listener) {
        clickListeners.remove(listener);
    }

    public void addFocusListener(FocusListener listener) {
        mainPanel.addFocusListener(listener);
    }

    public void setEnabled(boolean isEnabled) {
        this.isEnabled = isEnabled;
        if(buttonType == BUTTON_TYPE_BUTTON) {
            buttonPanel.setStyleName(
                    isEnabled ? "button_Enabled":"button_Disabled");
        }
        setTitle(this.isEnabled ? tooltip:"");
    }

    public boolean isEnabled() {
        return isEnabled;
    }

    public void setCaption(String caption) {
        this.caption = caption;
        label.setHTML(caption);
    }

    public void setButtonType(int type) {
        this.currentType = type;
    }

    public int getButtonType() {
        return currentType;
    }

    protected void setClientWidth(String clientWidth) {
    }

    public int getFilledWidth() {
        if(isVerticalLayout()) {
            return 0;
        } else {
            return getOffsetWidth() - getCaptionOffsetWidth();
        }
    }

    protected void fireLinkedFormSelectionEvent() {
    }

    public void setTooltip(String tooltip) {
        this.tooltip = tooltip;
        setTitle(tooltip);
    }

    public int getClientWidth() {
        return 0;
    }

    public boolean allowColspanning() {
        return false;
    }

}
