/*
 * Copyright (c) 2008-2013 Haulmont. All rights reserved.
 * Use is subject to license terms, see http://www.cuba-platform.com/license for details.
 */

package com.haulmont.cuba.desktop.gui.components;

import com.haulmont.cuba.gui.ComponentsHelper;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.components.SplitPanel;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Element;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.*;

/**
 * @author krivopustov
 * @version $Id$
 */
public class DesktopSplitPanel
        extends DesktopAbstractComponent<JSplitPane>
        implements SplitPanel, Component.HasSettings {

    protected boolean applyNewPosition = true;
    protected int position = 50;

    protected Map<String, Component> componentByIds = new HashMap<>();
    protected Collection<Component> ownComponents = new LinkedHashSet<>();

    public DesktopSplitPanel() {
        impl = new JSplitPane() {
            @Override
            public void paint(Graphics g) {
                super.paint(g);

                if (applyNewPosition) {
                    double ratio = position / 100.0;

                    impl.setDividerLocation(ratio);
                    impl.setResizeWeight(ratio);
                    applyNewPosition = false;
                }
            }
        };

        impl.getLeftComponent().setMinimumSize(new Dimension());
        impl.getRightComponent().setMinimumSize(new Dimension());
    }

    @Override
    public int getOrientation() {
        return impl.getOrientation() == JSplitPane.HORIZONTAL_SPLIT ? ORIENTATION_HORIZONTAL : ORIENTATION_VERTICAL;
    }

    @Override
    public void setOrientation(int orientation) {
        impl.setOrientation(orientation == ORIENTATION_HORIZONTAL ? JSplitPane.HORIZONTAL_SPLIT : JSplitPane.VERTICAL_SPLIT);
    }

    @Override
    public void setSplitPosition(int pos) {
        if (pos < 0 || pos > 100) {
            throw new IllegalArgumentException("Split position must be between 0 and 100");
        }

        this.position = pos;
        this.applyNewPosition = true;

        impl.revalidate();
        impl.repaint();
    }

    @Override
    public void setLocked(boolean locked) {
    }

    @Override
    public boolean isLocked() {
        return false;
    }

    @Override
    public void setPositionUpdateListener(PositionUpdateListener positionListener) {
        // not supported
    }

    @Override
    public PositionUpdateListener getPositionUpdateListener() {
        // not supported
        return null;
    }

    @Override
    public void add(Component component) {
        JComponent jComponent = DesktopComponentsHelper.getComposition(component);
        jComponent.setMinimumSize(new Dimension());
        if (ownComponents.isEmpty()) {
            impl.setLeftComponent(jComponent);
        } else {
            impl.setRightComponent(jComponent);
        }

        if (component.getId() != null) {
            componentByIds.put(component.getId(), component);
            if (frame != null) {
                frame.registerComponent(component);
            }
        }
        ownComponents.add(component);
    }

    @Override
    public void remove(Component component) {
        JComponent jComponent = DesktopComponentsHelper.getComposition(component);
        impl.remove(jComponent);

        if (component.getId() != null) {
            componentByIds.remove(component.getId());
        }
        ownComponents.remove(component);
    }

    @Override
    public <T extends Component> T getOwnComponent(String id) {
        return (T) componentByIds.get(id);
    }

    @Nullable
    @Override
    public <T extends Component> T getComponent(String id) {
        return ComponentsHelper.getComponent(this, id);
    }

    @Nonnull
    @Override
    public <T extends Component> T getComponentNN(String id) {
        T component = getComponent(id);
        if (component == null) {
            throw new IllegalArgumentException(String.format("Not found component with id '%s'", id));
        }
        return component;
    }

    @Override
    public Collection<Component> getOwnComponents() {
        return Collections.unmodifiableCollection(ownComponents);
    }

    @Override
    public Collection<Component> getComponents() {
        return ComponentsHelper.getComponents(this);
    }

    @Override
    public void applySettings(Element element) {
        Element e = element.element("position");
        if (e != null) {
            String value = e.attributeValue("value");
            if (!StringUtils.isBlank(value)) {
                // ignore defaults
                this.applyNewPosition = false;

                impl.setDividerLocation(Integer.valueOf(value));
                impl.setResizeWeight(position / 100.0);
            }
        }
    }

    @Override
    public boolean saveSettings(Element element) {
        int location = impl.getLastDividerLocation();
        if (location < 0) {
            return false; // most probably user didn't change the divider location
        }

        Element e = element.element("position");
        if (e == null)
            e = element.addElement("position");
        e.addAttribute("value", String.valueOf(location));
        return true;
    }
}
@@ -522,24 +522,73 @@
 x.swing.*;%0D%0A
+import javax.swing.plaf.synth.SynthSplitPaneUI;%0D%0A
 import java.
@@ -591,24 +591,24 @@
 ava.awt.*;%0D%0A
-
 import java.
@@ -700,25 +700,16 @@
 litPanel
-%0D%0A       
  extends
@@ -745,25 +745,16 @@
 litPane%3E
-%0D%0A       
  impleme
@@ -876,24 +876,74 @@
 on = 50;%0D%0A%0D%0A
+    protected boolean positionChanged = false;%0D%0A%0D%0A
     protecte
@@ -1525,32 +1525,32 @@
 %0A            %7D%0D%0A
-
         %7D;%0D%0A%0D%0A  
@@ -1543,24 +1543,395 @@
       %7D;%0D%0A%0D%0A
+        impl.setUI(new SynthSplitPaneUI() %7B%0D%0A                       @Override%0D%0A                       protected void dragDividerTo(int location) %7B%0D%0A                           super.dragDividerTo(location);%0D%0A%0D%0A                           // user touched split divider%0D%0A                           positionChanged = true;%0D%0A                       %7D%0D%0A                   %7D);%0D%0A%0D%0A
         impl
@@ -5377,24 +5377,70 @@
 on = false;%0D
+%0A                this.positionChanged = true;%0D
 %0A%0D%0A         
@@ -5668,78 +5668,27 @@
    i
-nt location = impl.getLastDividerLocation();%0D%0A        if (location %3C 0
+f (!positionChanged
 ) %7B%0D
@@ -5777,32 +5777,95 @@
 n%0D%0A        %7D%0D%0A%0D%0A
+        int location = impl.getUI().getDividerLocation(impl);%0D%0A
         Element 
@@ -5920,16 +5920,18 @@
 == null)
+ %7B
 %0D%0A      
@@ -5965,32 +5965,43 @@
 t(%22position%22);%0D%0A
+        %7D%0D%0A
         e.addAtt

Fix save settings for desktop split panel #PL-3774