/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you 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 org.apache.hupa.client.ui;

<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
import org.apache.hupa.client.activity.WestActivity;
import org.apache.hupa.shared.domain.ImapFolder;
import org.apache.hupa.shared.domain.User;
import org.apache.hupa.shared.events.LoadMessagesEvent;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;

/**
 * MainView acts like a container of other widgets which will get displayed
 * after the user successfully logged in
 * 
 * 
 */
public class WestView extends Composite implements WestActivity.Displayable {

	protected User user;
	private CellTree cellTree;
<<<<<<< HEAD

	@Inject
	public WestView(final EventBus eventBus) {
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			@SuppressWarnings("unchecked")
			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				SingleSelectionModel<ImapFolder> selectionModel = (SingleSelectionModel<ImapFolder>) event.getSource();
				eventBus.fireEvent(new LoadMessagesEvent(user, selectionModel.getSelectedObject()));
			}
		});
//		viewModel.setSelectionModel(selectionModel);

		CellTree.Resources res = GWT.create(CellTree.BasicResources.class);
		cellTree = new CellTree(null, res);
		cellTree.setAnimationEnabled(true);
		initWidget(cellTree);

	}

	private final SingleSelectionModel<ImapFolder> selectionModel = new SingleSelectionModel<ImapFolder>(
	        new ProvidesKey<ImapFolder>() {
		        @Override
		        public Object getKey(ImapFolder item) {
			        return item == null ? null : item.getFullName();
		        }
	        });

	public Widget asWidget() {
		return this;
=======
=======
>>>>>>> Change to new mvp framework - first step
import java.util.ArrayList;
import java.util.List;

import org.apache.hupa.client.HupaCSS;
import org.apache.hupa.client.HupaConstants;
import org.apache.hupa.client.HupaMessages;
=======
>>>>>>> refactoring.
import org.apache.hupa.client.activity.WestActivity;
import org.apache.hupa.shared.domain.ImapFolder;
import org.apache.hupa.shared.domain.User;
import org.apache.hupa.shared.events.LoadMessagesEvent;
<<<<<<< HEAD
import org.apache.hupa.shared.events.LoginEvent;
import org.apache.hupa.shared.events.LoginEventHandler;
import org.apache.hupa.shared.events.LogoutEvent;
import org.apache.hupa.shared.events.LogoutEventHandler;
import org.apache.hupa.shared.events.MoveMessageEvent;
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
import org.apache.hupa.shared.proxy.IMAPFolderProxy;
=======
>>>>>>> Change to new mvp framework - first step
=======
import org.apache.hupa.shared.proxy.IMAPFolderProxy;
>>>>>>> Aim to make the front end view work after the server side's IMAPFolder services RF being working, but there are issues on RF's find* method, I think.
=======
import org.apache.hupa.shared.proxy.ImapFolder;
>>>>>>> Make the ValueProxy(ImapFolder) work with Manolo's patch. Hupa can display folders in west view with RequestFactory now.
=======
>>>>>>> Allow client can use the domain entity interface.
import org.apache.hupa.widgets.event.EditEvent;
import org.apache.hupa.widgets.event.EditHandler;
import org.apache.hupa.widgets.ui.EnableHyperlink;
import org.apache.hupa.widgets.ui.HasEditable;
import org.apache.hupa.widgets.ui.HasEnable;
import org.apache.hupa.widgets.ui.Loading;
import org.apache.hupa.widgets.ui.RndPanel;
=======
>>>>>>> refactoring.

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;

/**
 * MainView acts like a container of other widgets which will get displayed
 * after the user successfully logged in
 * 
 * 
 */
public class WestView extends Composite implements WestActivity.Displayable {

<<<<<<< HEAD
    private DockPanel dockPanel;
    private VerticalPanel north;
    private HupaConstants constants;
<<<<<<< HEAD
<<<<<<< HEAD
    private VerticalPanel west;
=======
    private RndPanel west;
>>>>>>> Change to new mvp framework - first step
=======
    private VerticalPanel west;
>>>>>>> decorate the theme
    private IMAPTreeImages tImages = GWT.create(IMAPTreeImages.class);
    private Tree folderTree = new Tree(tImages, true);
  
    private Widget centerWidget;
    private RndPanel center;
    private IMAPMessageListView mListView;
    private HupaMessages messages;
    private VerticalPanel folderPanel = new VerticalPanel();
    private Panel westPanel = new HorizontalPanel();
    private HorizontalPanel folderButtonBar = new HorizontalPanel();
    private EnableHyperlink newFolderButton;
    private EnableHyperlink renameFolderButton;
    private EnableHyperlink deleteFolderButton;
    private ConfirmDialogBox confirmFolderDeleteBox = new ConfirmDialogBox();
    private Loading loader;
    private Loading messageLoader = new Loading();
    private List<DropController> dropControllerList = new ArrayList<DropController>();
    private EventBus bus;
    private PagingScrollTableRowDragController controller;
    protected User user;
    private TreeViewModel viewModel;
    
    @Inject
    public WestView(FolderTreeViewModel viewModel, final EventBus eventBus, PagingScrollTableRowDragController controllerProvider, HupaConstants constants, HupaMessages messages) {
    	this.viewModel = viewModel;
    	selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
=======
	protected User user;
	private FoldersCellTree cellTree;
>>>>>>> refactoring.
=======
>>>>>>> make folder list panel work as expected

	@Inject
	public WestView(final EventBus eventBus) {
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			@SuppressWarnings("unchecked")
			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				SingleSelectionModel<ImapFolder> selectionModel = (SingleSelectionModel<ImapFolder>) event.getSource();
				eventBus.fireEvent(new LoadMessagesEvent(user, selectionModel.getSelectedObject()));
<<<<<<< HEAD
	            
            }});
    	viewModel.setSelectionModel(selectionModel);
        this.constants = constants;
        this.messages = messages;
        this.controller = controllerProvider;
        this.bus = eventBus;
        loader = new Loading(constants.loading());
<<<<<<< HEAD
<<<<<<< HEAD
        newFolderButton = new EnableHyperlink(constants.newFolder(), null);
        renameFolderButton = new EnableHyperlink(constants.renameFolder(), null);
        deleteFolderButton = new EnableHyperlink(constants.deleteFolder(), null);
=======
        newFolderButton = new EnableHyperlink(constants.newFolder(), "");
        renameFolderButton = new EnableHyperlink(constants.renameFolder(), "");
        deleteFolderButton = new EnableHyperlink(constants.deleteFolder(), "");
>>>>>>> Change to new mvp framework - first step
=======
        newFolderButton = new EnableHyperlink(constants.newFolder(), null);
        renameFolderButton = new EnableHyperlink(constants.renameFolder(), null);
        deleteFolderButton = new EnableHyperlink(constants.deleteFolder(), null);
>>>>>>> 
        
        dockPanel = new DockPanel();

        dockPanel.setSpacing(10);
        dockPanel.setWidth("100%");

        // Not used so far
        // createNorth();
        // dockPanel.add(north, DockPanel.NORTH);
        // dockPanel.setCellHorizontalAlignment(north, DockPanel.ALIGN_RIGHT);
        
        createWest();
        dockPanel.add(west, DockPanel.WEST);
        dockPanel.setCellWidth(west, "160px");

        createCenter();
        dockPanel.add(center, DockPanel.CENTER);
        dockPanel.setCellHorizontalAlignment(center, DockPanel.ALIGN_LEFT);

<<<<<<< HEAD
<<<<<<< HEAD
        west.setWidth("100%");
=======
>>>>>>> Change to new mvp framework - first step
=======
        west.setWidth("100%");
<<<<<<< HEAD
>>>>>>> decorate the theme
        initWidget(west);
    }

    private void createWest() {
<<<<<<< HEAD
<<<<<<< HEAD
=======
//        initWidget(west);
        cellTree = new FolderTree(viewModel, null, res);
        putCellTree();
        
    }

	public final ProvidesKey<ImapFolder> KEY_PROVIDER = new ProvidesKey<ImapFolder>() {
		@Override
		public Object getKey(ImapFolder item) {
			return item == null ? null : item.getFullName();
		}
	};
    CellTree.Resources res = GWT.create(CellTree.BasicResources.class);
    final SingleSelectionModel<ImapFolder> selectionModel =
    	      new SingleSelectionModel<ImapFolder>(KEY_PROVIDER);
    CellTree cellTree;
    FlowPanel panel = new FlowPanel();
    private void putCellTree() {

//        TreeNode rootNode = cellTree.getRootTreeNode();
//        TreeNode firstPlaylist = rootNode.setChildOpen(0, true);
//        firstPlaylist.setChildOpen(0, true);
    	initWidget(cellTree);
    	cellTree.setAnimationEnabled(true);
    	
    }

	private void createWest() {
>>>>>>> Fix issue #15.
        west = new VerticalPanel();
<<<<<<< HEAD
=======
        west = new RndPanel();
>>>>>>> Change to new mvp framework - first step
=======
        west = new VerticalPanel();
>>>>>>> decorate the theme
=======
//        folderTree.clear();
>>>>>>> fix bugs, including 1)folders appending on west panel; 2)unread email folder's been frozen exception; 3)back, logout, ...buttons wired behavior.
        west.add(folderTree);
        west.addStyleName(HupaCSS.C_tree_container);

        folderTree.setAnimationEnabled(true);
        folderPanel.setSpacing(5);

        folderButtonBar.setSpacing(3);
        folderButtonBar.add(newFolderButton);
        folderButtonBar.add(renameFolderButton);
        folderButtonBar.add(deleteFolderButton);
        folderPanel.add(folderButtonBar);
        folderPanel.add(folderTree);
        westPanel.add(loader);
        confirmFolderDeleteBox.setText(messages.confirmDeleteFolder());
        bus.addHandler(LoginEvent.TYPE, new LoginEventHandler() {

            public void onLogin(LoginEvent event) {
                user = event.getUser();
            }

        });
        bus.addHandler(LogoutEvent.TYPE, new LogoutEventHandler() {

            public void onLogout(LogoutEvent event) {
                user = null;
            }

        });
        west.add(westPanel);
    }

    @SuppressWarnings("unused")
    private void createNorth() {
        north = new VerticalPanel();
        north.setWidth("100%");
    }

    private void createCenter() {
        center = new RndPanel();
        center.setWidth("100%");
        // FIXME: 
        if (mListView != null)
            center.add(mListView);
    }


    /*
     * (non-Javadoc)
     * @see org.apache.hupa.client.mvp.MainPresenter.Display#bindTreeItems(java.util.ArrayList)
     */
    public void bindTreeItems(List<IMAPTreeItem> treeList) {
        folderTree.clear();
        for (DropController dropController : dropControllerList) {
            controller.unregisterDropController(dropController);
        }

        for (IMAPTreeItem iTreeItem : treeList) {
            bindDropController(iTreeItem);
            folderTree.addItem(iTreeItem);

            if (((ImapFolder) iTreeItem.getUserObject()).getFullName().equalsIgnoreCase(user.getSettings().getInboxFolderName())) {
                folderTree.setSelectedItem(iTreeItem, false);
            }

        }
    }

    /**
     * Bind a IMAPFolderDropController to the given Item and all its childs
     * 
     * @param item
     */
    private void bindDropController(IMAPTreeItem item) {
        IMAPFolderDropController dropController = new IMAPFolderDropController(item);
        controller.registerDropController(dropController);
        dropControllerList.add(dropController);

        if (item.getChildCount() > 0) {
            for (int i = 0; i < item.getChildCount(); i++) {
                bindDropController((IMAPTreeItem) item.getChild(i));
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getTree()
     */
    public HasSelectionHandlers<TreeItem> getTree() {
        return folderTree;
    }

    /*
     * (non-Javadoc)
     * 
     * @see net.customware.gwt.presenter.client.widget.WidgetDisplay#asWidget()
     */
    public Widget asWidget() {
        return this;
    }


    /*
     * (non-Javadoc)
     * @see org.apache.hupa.client.mvp.MainPresenter.Display#setLoadingFolders(boolean)
     */
    public void setLoadingFolders(boolean load) {
        if (load) {
            loader.show();
            westPanel.clear();
            westPanel.add(loader);
        } else {
            westPanel.clear();
            westPanel.add(folderPanel);
        }
    }

    /*
     * (non-Javadoc)
     * @see org.apache.hupa.client.mvp.MainPresenter.Display#setLoadingMessage(boolean)
     */
    public void setLoadingMessage(boolean load) {
        if (load) {
            messageLoader.show();
        } else {
            messageLoader.hide();
        }
    }

    /**
     * Drop controller which handle drop on TreeItems
     * 
     * 
     */
    private class IMAPFolderDropController extends SimpleDropController {
        private IMAPTreeItem item;

        public IMAPFolderDropController(IMAPTreeItem item) {
            super(item.getWidget());
            this.item = item;
        }

        /**
         * Veto the Drop if the folder is the same
         */
        @Override
        public void onPreviewDrop(DragContext context) throws VetoDragException {
            if (item.equals(folderTree.getSelectedItem())) {
                throw new VetoDragException();
            }
        }

        /**
         * Set the right unseen count on the folders and fire an event
         */
        @Override
        public void onDrop(DragContext context) {
            IMAPTreeItem oldTreeItem = (IMAPTreeItem) folderTree.getSelectedItem();
            Message message = (Message) controller.getDragValue();
            if (message.getFlags().contains(IMAPFlag.SEEN) == false) {
                oldTreeItem.decreaseUnseenMessageCount();
                item.increaseUnseenMessageCount();
            }
            bus.fireEvent(new MoveMessageEvent(user, (ImapFolder) oldTreeItem.getUserObject(), (ImapFolder) item.getUserObject(), message));
        }

        /**
         * Update the proxy widget to show its valid to drop it
         * 
         */
        @Override
        public void onEnter(DragContext context) {
            if (item.equals(folderTree.getSelectedItem()) == false) {
                controller.getCurrentProxy().setIsValid(true);
            }
            super.onEnter(context);
        }

        /**
         * Update the proxy widget to show its invalid to drop it
         */
        @Override
        public void onLeave(DragContext context) {
            controller.getCurrentProxy().setIsValid(false);
            super.onLeave(context);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getRenameClick()
     */
    public HasClickHandlers getRenameClick() {
        return renameFolderButton;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getDeleteEnable()
     */
    public HasEnable getDeleteEnable() {
        return deleteFolderButton;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getNewEnable()
     */
    public HasEnable getNewEnable() {
        return newFolderButton;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getRenameEnable()
     */
    public HasEnable getRenameEnable() {
        return renameFolderButton;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getDeleteClick()
     */
    public HasClickHandlers getDeleteClick() {
        return deleteFolderButton;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getNewClick()
     */
    public HasClickHandlers getNewClick() {
        return newFolderButton;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getDeleteConfirmDialog
     * ()
     */
    public HasDialog getDeleteConfirmDialog() {
        return confirmFolderDeleteBox;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#getDeleteConfirmClick
     * ()
     */
    public HasClickHandlers getDeleteConfirmClick() {
        return confirmFolderDeleteBox;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#deleteSelectedFolder
     * ()
     */
    public void deleteSelectedFolder() {
        folderTree.getSelectedItem().remove();

        // Select the INBOX after delete folder
        for (int i = 0; i < folderTree.getItemCount(); i++) {
            IMAPTreeItem item = (IMAPTreeItem) folderTree.getItem(i);
            if (((ImapFolder) item.getUserObject()).getFullName().equalsIgnoreCase(user.getSettings().getInboxFolderName())) {
                folderTree.setSelectedItem(item, true);
                break;
            }
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.hupa.client.mvp.IMAPFolderPresenter.Display#createFolder(org
     * .apache.hupa.client.widgets.EditHandler)
     */
    public HasEditable createFolder(EditHandler handler) {
        final IMAPTreeItem selected = (IMAPTreeItem) folderTree.getSelectedItem();
        
        if (selected.isEdit())
            return null;
        
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
        IMAPFolderProxy oldFolder = (IMAPFolderProxy) selected.getUserObject();

        // Generate a new folder with a whitespace as name, this is needed as
        // workaround
        IMAPFolderProxy folder = (IMAPFolderProxy)new IMAPFolder(oldFolder.getFullName() + oldFolder.getDelimiter() + " ");
=======
        IMAPFolder oldFolder = (IMAPFolder) selected.getUserObject();

        // Generate a new folder with a whitespace as name, this is needed as
        // workaround
        IMAPFolder folder = new IMAPFolder(oldFolder.getFullName() + oldFolder.getDelimiter() + " ");
>>>>>>> Change to new mvp framework - first step
=======
        IMAPFolderProxy oldFolder = (IMAPFolderProxy) selected.getUserObject();

        // Generate a new folder with a whitespace as name, this is needed as
        // workaround
        IMAPFolderProxy folder = (IMAPFolderProxy)new IMAPFolder(oldFolder.getFullName() + oldFolder.getDelimiter() + " ");
>>>>>>> Aim to make the front end view work after the server side's IMAPFolder services RF being working, but there are issues on RF's find* method, I think.
=======
        ImapFolder oldFolder = (ImapFolder) selected.getUserObject();

        // Generate a new folder with a whitespace as name, this is needed as
        // workaround
        ImapFolder folder = (ImapFolder)new ImapFolderImpl(oldFolder.getFullName() + oldFolder.getDelimiter() + " ");
>>>>>>> Make the ValueProxy(ImapFolder) work with Manolo's patch. Hupa can display folders in west view with RequestFactory now.
        folder.setDelimiter(oldFolder.getDelimiter());

        final IMAPTreeItem newItem = new IMAPTreeItem(folder);

        // add the new item as child
        folderTree.getSelectedItem().addItem(newItem);
        newItem.addEditHandler(handler);
        newItem.addEditHandler(new EditHandler() {

            public void onEditEvent(EditEvent event) {
                if (event.getEventType().equals(EditEvent.EventType.Cancel)) {
                    // remove the folder
                    newItem.remove();
                    folderTree.setSelectedItem(selected, false);
                } else if (event.getEventType().equals(EditEvent.EventType.Stop)) {
                    // add the new item to dnd controller 
                    bindDropController(newItem);
                    // Select the parent folder to avoid an issue in gmail, because
                    // the new folder takes a while until it is available
                    folderTree.setSelectedItem(selected, false);
                }
            }

        });
        // Expand the parent
        folderTree.getSelectedItem().setState(true, false);

        // Select the new folder and start editing it
        folderTree.setSelectedItem(newItem, false);
        newItem.startEdit();

        // reset the text of the new item (remove the whitespace)
        newItem.setText("");
        
        return newItem;
    }

    /*
     * (non-Javadoc)
     * 
     * @seeorg.apache.hupa.client.mvp.IMAPFolderPresenter.Display#
     * decreaseUnseenMessageCount(org.apache.hupa.shared.data.IMAPFolder, int)
     */
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
    public void decreaseUnseenMessageCount(IMAPFolderProxy folder, int amount) {
=======
    public void decreaseUnseenMessageCount(IMAPFolder folder, int amount) {
>>>>>>> Change to new mvp framework - first step
=======
    public void decreaseUnseenMessageCount(IMAPFolderProxy folder, int amount) {
>>>>>>> Aim to make the front end view work after the server side's IMAPFolder services RF being working, but there are issues on RF's find* method, I think.
=======
    public void decreaseUnseenMessageCount(ImapFolder folder, int amount) {
>>>>>>> Make the ValueProxy(ImapFolder) work with Manolo's patch. Hupa can display folders in west view with RequestFactory now.
        int count = folderTree.getItemCount();
        for (int i = 0; i < count; i++) {
            IMAPTreeItem item = findTreeItemForFolder((IMAPTreeItem) folderTree.getItem(i), folder);
            if (item != null) {
                item.descreaseUnseenMessageCount(amount);
                break;
            }

        }
    }

    /*
     * (non-Javadoc)
     * 
     * @seeorg.apache.hupa.client.mvp.IMAPFolderPresenter.Display#
     * increaseUnseenMessageCount(org.apache.hupa.shared.data.IMAPFolder, int)
     */
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
    public void increaseUnseenMessageCount(IMAPFolderProxy folder, int amount) {
=======
    public void increaseUnseenMessageCount(IMAPFolder folder, int amount) {
>>>>>>> Change to new mvp framework - first step
=======
    public void increaseUnseenMessageCount(IMAPFolderProxy folder, int amount) {
>>>>>>> Aim to make the front end view work after the server side's IMAPFolder services RF being working, but there are issues on RF's find* method, I think.
=======
    public void increaseUnseenMessageCount(ImapFolder folder, int amount) {
>>>>>>> Make the ValueProxy(ImapFolder) work with Manolo's patch. Hupa can display folders in west view with RequestFactory now.
        int count = folderTree.getItemCount();
        for (int i = 0; i < count; i++) {
            IMAPTreeItem item = findTreeItemForFolder((IMAPTreeItem) folderTree.getItem(i), folder);
            if (item != null) {
                item.increaseUnseenMessageCount(amount);
                break;
            }

        }
    }

    
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
    private IMAPTreeItem findTreeItemForFolder(IMAPTreeItem item, IMAPFolderProxy folder) {
=======
    private IMAPTreeItem findTreeItemForFolder(IMAPTreeItem item, IMAPFolder folder) {
>>>>>>> Change to new mvp framework - first step
=======
    private IMAPTreeItem findTreeItemForFolder(IMAPTreeItem item, IMAPFolderProxy folder) {
>>>>>>> Aim to make the front end view work after the server side's IMAPFolder services RF being working, but there are issues on RF's find* method, I think.
        if (folder.getFullName().equalsIgnoreCase(((IMAPFolder) item.getUserObject()).getFullName())) {
=======
    private IMAPTreeItem findTreeItemForFolder(IMAPTreeItem item, ImapFolder folder) {
        if (folder.getFullName().equalsIgnoreCase(((ImapFolder) item.getUserObject()).getFullName())) {
>>>>>>> Make the ValueProxy(ImapFolder) work with Manolo's patch. Hupa can display folders in west view with RequestFactory now.
            return item;
        }
        for (int i = 0; i < item.getChildCount(); i++) {
            IMAPTreeItem tItem = findTreeItemForFolder((IMAPTreeItem) item.getChild(i), folder);
            if (tItem != null) {
                return tItem;
            }
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * @see org.apache.hupa.client.mvp.MainPresenter.Display#updateTreeItem(org.apache.hupa.shared.data.IMAPFolder)
     */
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
    public void updateTreeItem(IMAPFolderProxy folder) {
=======
    public void updateTreeItem(IMAPFolder folder) {
>>>>>>> Change to new mvp framework - first step
=======
    public void updateTreeItem(IMAPFolderProxy folder) {
>>>>>>> Aim to make the front end view work after the server side's IMAPFolder services RF being working, but there are issues on RF's find* method, I think.
=======
    public void updateTreeItem(ImapFolder folder) {
>>>>>>> Make the ValueProxy(ImapFolder) work with Manolo's patch. Hupa can display folders in west view with RequestFactory now.
        int count = folderTree.getItemCount();
        for (int i = 0; i < count; i++) {
            IMAPTreeItem item = findTreeItemForFolder((IMAPTreeItem) folderTree.getItem(i), folder);
            if (item != null) {
                item.setUserObject(folder);
                break;
            }
        }
    }
=======
			}
		});
//		viewModel.setSelectionModel(selectionModel);

		CellTree.Resources res = GWT.create(CellTree.BasicResources.class);
		cellTree = new CellTree(null, res);
		cellTree.setAnimationEnabled(true);
		initWidget(cellTree);
>>>>>>> refactoring.

	}

	private final SingleSelectionModel<ImapFolder> selectionModel = new SingleSelectionModel<ImapFolder>(
	        new ProvidesKey<ImapFolder>() {
		        @Override
		        public Object getKey(ImapFolder item) {
			        return item == null ? null : item.getFullName();
		        }
	        });

<<<<<<< HEAD
	@Override
	public void setUser(User user) {
		this.user = user;
		
<<<<<<< HEAD
>>>>>>> Change to new mvp framework - first step
=======
>>>>>>> Change to new mvp framework - first step
=======
	public Widget asWidget() {
		return this;
>>>>>>> refactoring.
	}
}
