function build(this)
%BUILD  Builds axes selector GUI.

%   Author: K. Gondoly, P. Gahinet
%   Copyright 1986-2004 The MathWorks, Inc.
%   $Revision: 1.1.6.2 $ $Date: 2004/04/11 00:17:39 $

% Style variables
UIColor = get(0,'DefaultUIControlBackground');
PointsToPixels = 72/get(0,'ScreenPixelsPerInch');
StdUnit = 'points';

% Set font size and weight
if isunix
   FontSize = 10;
else
   FontSize = 8;
end   
FigWidth = 150+(this.Size(2)*20);
FigHeight = 120+(this.Size(1)*20);
FigPos = [20 20 FigWidth FigHeight];

ChannelFig=figure('Units',StdUnit,...
   'Position',PointsToPixels*FigPos,...
   'Number','off',...
   'IntegerHandle','off',...
   'HandleVisibility','Callback',...
   'Menu','none',...
   'Name',this.Name,...
   'Color',UIColor,...
   'CloseRequestFcn',{@LocalHide this},...
   'Visible','off',...
   'DockControls', 'off');

% UI controls
CloseButton = uicontrol(ChannelFig,...
   'Unit',StdUnit,...
   'Background',UIColor,...
   'Position',PointsToPixels*[FigWidth-75-60 10 60 20],...
   'Unit','normalized',...
   'Style','pushbutton',...
   'String','Close',...
   'callback',{@LocalHide this});   
HelpButton = uicontrol(ChannelFig,...
   'Unit',StdUnit,...
   'Background',UIColor,...
   'Position',PointsToPixels*[FigWidth-70 10 60 20],...
   'Unit','normalized',...
   'Style','pushbutton',...
   'String','Help',...
   'Callback','ctrlguihelp(''response_ioselector'');');

% Axes
ax = axes('Parent',ChannelFig,...
   'ButtonDownFcn',{@LocalSelectGroup this},...
   'XColor',[0 0 0],...
   'YColor',[0 0 0],...
   'Color',UIColor,...
   'Unit',StdUnit,...
   'Position',PointsToPixels*[10 40 FigPos(3)-20 FigPos(4)-50],...
   'Box','on',...
   'Ydir','reverse',...
   'Xlim',[0 this.Size(2)+1],...
   'Ylim',[0 this.Size(1)+1],...
   'Xtick',[],...
   'Ytick',[]);
set(ax,'unit','norm');

% [ all ] Text
AllText=text(0.5,0.5,'[ all ]', ...
   'Parent',ax, ...
   'Interpreter','none', ...
   'ButtonDownFcn',{@LocalSelectAll this}, ...
   'Color',[0 0 0],...
   'FontSize',FontSize, ...
   'HorizontalAlignment','center', ...
   'VerticalAlignment','middle');

% Row labels
RowLabels = zeros(this.Size(1),1);
for ct=1:this.Size(1)
   RowLabels(ct) = text(0.5,ct+0.5,'', ...
      'Parent',ax, ...
      'Interpreter','none', ...
      'ButtonDownFcn',{@LocalSelectRow this ct}, ...
      'Color',[0 0 0],...
      'FontSize',FontSize, ...
      'HorizontalAlignment','center', ...
      'VerticalAlignment','middle');
end

% Column labels
ColumnLabels = zeros(this.Size(2),1);
for ct=1:this.Size(2)
   ColumnLabels(ct) = text(ct+0.5,0.5,'', ...
      'Parent',ax, ...
      'Interpreter','none', ...
      'ButtonDownFcn',{@LocalSelectCol this ct}, ...
      'Color',[0 0 0],...
      'FontSize',FontSize, ...
      'HorizontalAlignment','center', ...
      'VerticalAlignment','middle');
end

% Dots and labels
Dots = zeros(this.Size);
for jloop=1:this.Size(2)
   for iloop=1:this.Size(1)
      Dots(iloop,jloop)=line(jloop+0.5,iloop+0.5, ...
         'Parent',ax, ...
         'Marker','o', ...
         'MarkerEdgeColor','k', ...
         'MarkerSize',7, ...
         'LineStyle','none', ...
         'ButtonDownFcn',{@LocalSelectDot this iloop jloop});
   end % for jloop
end % for iloop

% Store handles
this.Handles = struct(...
   'Figure',ChannelFig,...
   'AllText',AllText,...
   'RowText',RowLabels,...
   'ColText',ColumnLabels,...
   'Dots',Dots);

%------------------------ Local Functions ---------------------------
function LocalHide(eventsrc,eventdata,this)
this.Visible = 'off';


function LocalSelectAll(eventsrc,eventdata,this)
% Select all
AllSelect = ~(all(this.RowSelection) & all(this.ColumnSelection));
% REVISIT: simplify when this.prop(i) = rhs works
% this.RowSelection(:) = AllSelect;
rs = this.RowSelection; rs(:) = AllSelect; this.RowSelection = rs;
cs = this.ColumnSelection; cs(:) = AllSelect; this.ColumnSelection = cs;


function LocalSelectRow(eventsrc,eventdata,this,i)
% Select given row. Clicking on a row toggles its visibility 
% RE: Effective visibility of dots in the row depends on column visibility too
NoSelect = all(~this.RowSelection) & all(~this.ColumnSelection);
% REVISIT: simplify when this.prop(i) = rhs works
RowSel = this.RowSelection;
RowSel(i) = ~RowSel(i);
this.RowSelection = RowSel;
if NoSelect
   % Turn on all columns of nothing selected initially
   cs = this.ColumnSelection; cs(:) = logical(1); this.ColumnSelection = cs;
end


function LocalSelectCol(eventsrc,eventdata,this,j)
% Select given column. Clicking on a column toggles its visibility 
NoSelect = all(~this.RowSelection) & all(~this.ColumnSelection);
% REVISIT: simplify when this.prop(i) = rhs works
ColSel = this.ColumnSelection;
ColSel(j) = ~ColSel(j);
this.ColumnSelection = ColSel;
if NoSelect
   % Turn on all rows of nothing selected initially
   rs = this.RowSelection; rs(:) = logical(1); this.RowSelection = rs;
end


function LocalSelectDot(eventsrc,eventdata,this,i,j)
% Select single (row,col) pair
RowSel = zeros(this.Size(1),1);
RowSel(i) = 1;
ColSel = zeros(this.Size(2),1);
ColSel(j) = 1;
this.RowSelection = logical(RowSel);
this.ColumnSelection = logical(ColSel);


function LocalSelectGroup(eventsrc,eventdata,this)
% Selects group of I/Os
ax = eventsrc;
H = this.Handles;

%---Get figure current point data
FigUnits=get(H.Figure,'Unit');
set(H.Figure,'unit','norm');
axpos=get(ax,'Position');
P=get(H.Figure,'CurrentPoint'); % initializes rbbox

% Draw the rubberband box
rect = rbbox;
rect(1)=max([0,(rect(1)-axpos(1))]);
rect(2)=max([0,(rect(2)-axpos(2))]);
rect(1:2)=max(0,rect(1:2)./axpos(3:4));
rect(3:4)=min(1,rect(3:4)./axpos(3:4));

% Get the current rectangle 
XV=[rect(1);rect(1)+rect(3);rect(1)+rect(3);rect(1);rect(1)];
YV=[rect(2);rect(2);rect(2)+rect(4);rect(2)+rect(4);rect(2)];

% Dot positions in [0 1]
Xdots = get(H.Dots,{'Xdata'});
Xdots = cat(1,Xdots{:})/(1+this.Size(2));
Ydots = get(H.Dots,{'Ydata'});
Ydots = 1-cat(1,Ydots{:})/(1+this.Size(1));

% Selected dots
indots = inpolygon(Xdots,Ydots,XV,YV);
indots = reshape(indots,this.Size);
if any(indots(:))
   this.RowSelection = any(indots,2);
   this.ColumnSelection = any(indots,1);
end

% Return figure back to original units
set(H.Figure,'Unit',FigUnits);

