/**
 *
 * Copyright (c) 2006-2015, Speedment, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * 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.speedment.internal.newgui;

import com.speedment.component.UserInterfaceComponent;
import com.speedment.event.ProjectLoaded;
import com.speedment.internal.gui.config.AbstractNodeProperty;
import com.speedment.internal.gui.config.AbstractParentProperty;
import com.speedment.internal.gui.config.ProjectProperty;
import com.speedment.internal.gui.icon.SpeedmentIcon;
import com.speedment.internal.newgui.util.UILoader;
import com.speedment.internal.newgui.util.UISession;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import static java.util.Objects.requireNonNull;
import static javafx.application.Platform.runLater;
import javafx.beans.binding.Bindings;
import static javafx.beans.binding.Bindings.createObjectBinding;
import javafx.collections.ListChangeListener;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import static javafx.scene.control.SelectionMode.MULTIPLE;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.paint.Color;

/**
 *
 * @author Emil Forslund
 */
public final class ProjectTreeController implements Initializable {
    
    private final UISession session;
    
    private @FXML TreeView<AbstractNodeProperty> hierarchy;
    
    private ProjectTreeController(UISession session) {
        this.session = requireNonNull(session);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        runLater(() -> populateTree(session.getProject()));
    }
    
    private void populateTree(ProjectProperty project) {
        requireNonNull(project);
        
        session.getSpeedment().getEventComponent().notify(new ProjectLoaded(project));

        hierarchy.setCellFactory(view -> {
            final TreeCell<AbstractNodeProperty> cell =  new TreeCell<AbstractNodeProperty>() {
                @Override
                protected void updateItem(AbstractNodeProperty item, boolean empty) {
                    // item can be null
                    super.updateItem(item, requireNonNull(empty));

                    if (item == null || empty) {
                        setGraphic(null);
                        textProperty().unbind();
                        styleProperty().unbind();
//                        backgroundProperty().unbind();

                    } else {
                        setGraphic(SpeedmentIcon.forNode(item));
                        textProperty().bind(item.nameProperty());

//                        backgroundProperty().bind(
//                            createObjectBinding(
//                                () -> item.enabledProperty().get() ?
//                                BG_ENABLED : BG_DISABLED, 
//                                item.enabledProperty()
//                            )
//                        );

//                        styleProperty().bind(
//                            createObjectBinding(
//                                () -> item.enabledProperty().get() ?
//                                "" : "-fx-background-color: lightgray;", 
//                                item.enabledProperty()
//                            )
//                        );
                    }
                }
            };
            
            return cell;
        });
        
        hierarchy.getSelectionModel().setSelectionMode(MULTIPLE);
        
        final UserInterfaceComponent ui = session.getSpeedment().getUserInterfaceComponent();
        Bindings.bindContent(
            ui.getCurrentSelection(),
            hierarchy.getSelectionModel().getSelectedItems()
        );
        
        hierarchy.setRoot(branch(project));
    }
    
    private TreeItem<AbstractNodeProperty> branch(AbstractNodeProperty node) {
        requireNonNull(node);
        
        final TreeItem<AbstractNodeProperty> branch = new TreeItem<>(node);
        branch.expandedProperty().bindBidirectional(node.expandedProperty());
        
        
        
        if (node instanceof AbstractParentProperty) {
            @SuppressWarnings("unchecked")
            final AbstractParentProperty<AbstractNodeProperty, ? extends AbstractNodeProperty> nodeAsParent 
                = (AbstractParentProperty<AbstractNodeProperty, ? extends AbstractNodeProperty>) node;
            
            nodeAsParent.stream()
                .map(this::branch)
                .forEach(branch.getChildren()::add);
            
            nodeAsParent.children().addListener((ListChangeListener.Change<? extends AbstractNodeProperty> c) -> {
                if (c.wasAdded()) {
                    c.getAddedSubList().stream()
                        .map(this::branch)
                        .forEach(branch.getChildren()::add);
                }
                
                if (c.wasRemoved()) {
                    c.getRemoved().stream()
                        .forEach(val -> branch.getChildren().removeIf(item -> val.equals(item.getValue())));
                }
            });
        }

        return branch;
    }
    
    public static Node create(UISession session) {
        return UILoader.create(session, "ProjectTree", ProjectTreeController::new);
	}
    
    private final static Background 
        BG_ENABLED = new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)),
        BG_DISABLED = new Background(new BackgroundFill(Color.LIGHTGRAY, CornerRadii.EMPTY, Insets.EMPTY));
    
}
@@ -3070,18 +3070,16 @@
 bind();%0A
-//
         
@@ -3098,40 +3098,63 @@
     
-backgroundProperty().unbind(
+setText(null);%0A                        setStyle(null
 );%0A
-%0A
     
@@ -3314,365 +3314,8 @@
 );%0A%0A
-//                        backgroundProperty().bind(%0A//                            createObjectBinding(%0A//                                () -%3E item.enabledProperty().get() ?%0A//                                BG_ENABLED : BG_DISABLED, %0A//                                item.enabledProperty()%0A//                            )%0A//                        );%0A%0A//
     
@@ -3356,18 +3356,16 @@
 ).bind(%0A
-//
         
@@ -3405,18 +3405,16 @@
 inding(%0A
-//
         
@@ -3474,18 +3474,16 @@
 get() ?%0A
-//
         
@@ -3520,42 +3520,52 @@
 -fx-
-background-color: lightgray
+text-fill: gray; -fx-font-style: italic
 ;%22, %0A
-//
     
@@ -3615,18 +3615,16 @@
 perty()%0A
-//
         
@@ -3645,18 +3645,16 @@
       )%0A
-//
         
@@ -4435,34 +4435,8 @@
 ));%0A
-        %0A        %0A        
 %0A   

Fix bug with nodes in TreeView