function this = TreeManager(rootnode,varargin)
% TREEMANAGER Constructor for @TreeManager object

% Author(s):  
% Revised:
% Copyright 1986-2001 The MathWorks, Inc.
% $Revision: 1.1.6.1 $ $Date: 2004/12/26 21:36:06 $

import com.mathworks.toolbox.timeseries.*;
import java.awt.dnd.*
import javax.swing.tree.*;

%% TO DO: Tree manager should create the tree not the tsviewer constructior

%% Create class instance
this = tsexplorer.TreeManager;

%% Assign specified properties
for k=1:(nargin-1)/2
    set(this,varargin{2*k-1},varargin{2*k});
end

%% Create the margin buttons
this.Margin = [uipanel('Parent',this.Figure,'Units','Characters'),...
               uipanel('Parent',this.Figure,'Units','Characters')];
set(this.Margin,'HighlightColor',get(this.Margin(1),'BackgroundColor'),...
    'ShadowColor',get(this.Margin(1),'BackgroundColor'))
set(this.Margin(1),'ButtonDownFcn',{@localLeftMarginDown this})
set(this.Margin(2),'ButtonDownFcn',{@localRightMarginDown this})

%% Create the tree
if isempty(this.Root)
    this.Root = rootnode;
end
[this.Tree, this.Treepanel] = ...
     uitree(this.Figure,'Root',rootnode.getTreeNodeInterface);
%% Remove component resizing listener since we are not using normalized
%% units (performance reasons)
L = get(this.Treepanel,'Listeners__');
for k=1:length(L)
    if strcmp(L(k).SourceObject.Name,'PixelBounds')
        L(k).Enable = 'off';
        break
    end
end
this.Tree.setDndEnabled(true); % Enable drag & drop
set(this.Treepanel,'Units','Characters','Hittest','off')
this.Tree.getTree.setCursor(java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

%% Figure resize behavior
set(this.Figure,'Units','Characters','ResizeFcn',{@localResize this})

%% Show a lower scrollbar
this.Tree.getScrollPane.setHorizontalScrollBarPolicy(32)

%% treemanager dropCallback method should be the target of drops
dropAdaptor = AxisDropAdaptor(this,'dropCallback',this.Tree.getTree,...
    TreePath([rootnode.getTreeNodeInterface;rootnode.down.right.getTreeNodeInterface]));
dropHandler = DropTarget(this.Tree.getTree,dropAdaptor);
this.Tree.getTree.setDropTarget(dropHandler);

%% Add Java related callbacks
this.addCallbacks;

%% Build node context menu listener 
this.Cmenulistener = uitreePopupListener;
this.Tree.getTree.addMouseListener(this.Cmenulistener);

%% Add UDD related listeners
this.addListeners

%% Size it
localResize(this.Figure,[],this)

function localResize(es,ed,h)

%% Main figure resize fcn

% Enforce minimum width to prevent panels uicontrols showing outside their
% permited extent
minwidth = 120; 
minmarginwidth = 30;

pos = get(es,'Position');
if ~isempty(h.Panel)
    % If the main panel size < minimum: First shrink the margins to honor
    % the new requested size up to a minimum of 5 characters. After that,
    % force the figure back to its mininum width
    if pos(3)-h.DialogPosition-h.HelpDialogPosition-1 <= minwidth
        marginwith = max(max(0.5*(pos(3)-1-minwidth),5),minmarginwidth); 
        pos(3) = minwidth+1+2*marginwith;
        h.HelpDialogPosition = marginwith;
        h.DialogPosition = marginwith;
        set(es,'Position',pos)
        pnlpos = hgconvertunits(es,...
             [h.DialogPosition 0 pos(3)-2*marginwith pos(4)],...
            'Characters',get(h.Panel,'Units'),get(h.Panel,'Parent'));
    else   
        pnlpos = hgconvertunits(es,...
        [max(h.DialogPosition,1) 0 pos(3)-max(h.DialogPosition,1)-h.HelpDialogPosition-1 pos(4)],...
        'Characters',get(h.Panel,'Units'),get(h.Panel,'Parent'));
    end
    set(h.Panel,'Position',pnlpos)
end


set(h.Treepanel,'Position',[0 0 max(1,h.DialogPosition-1) pos(4)])
set(h.HelpPanel,'Position',[max(1,pos(3)-h.HelpDialogPosition) 0 h.HelpDialogPosition pos(4)])
set(h.Margin(1),'Position',[max(1,h.DialogPosition-1) 0 1 pos(4)])
set(h.Margin(2),'Position',[max(1,pos(3)-h.HelpDialogPosition-1) 0 1 pos(4)])


function localLeftMarginDown(es,ed,this)

set(this.Figure,'WindowButtonMotionFcn',{@localSlideLeftMargin this},'WindowButtonUpFcn',...
    {@localMarginUp this},'BusyAction','Cancel','Interruptible','off','Pointer','Left');

function localRightMarginDown(es,ed,this)

set(this.Figure,'WindowButtonMotionFcn',{@localSlideRightMargin this},'WindowButtonUpFcn',...
    {@localMarginUp this},'BusyAction','Cancel','Interruptible','off','Pointer','Left');


function localMarginUp(es,ed,this)

% set(this.Figure,'WindowButtonMotionFcn','','WindowButtonUpFcn','',...
%     'BusyAction','Queue','Interruptible','on','Pointer','Arrow');

set(this.Figure,'WindowButtonMotionFcn',{@tshoverfig this},'WindowButtonUpFcn','',...
    'Pointer','Arrow','Interruptible','on');

function localSlideLeftMargin(es,ed,this)

thispt = get(this.Figure,'CurrentPoint');
this.DialogPosition = thispt(1);
localResize(this.Figure,ed,this)

function localSlideRightMargin(es,ed,this)

pos = get(this.Figure,'Position');
thispt = get(this.Figure,'CurrentPoint');
this.HelpDialogPosition = max(1,pos(3)-thispt(1));
localResize(this.Figure,ed,this)
   
