function [p] = gui_eeg_open(p,command,parent)

% gui_eeg_open - Load an EEG data file into matlab workspace
%
% Usage: [p] = gui_eeg_open(p,[command],[parent])
%
% p is a structure, generated by 'eeg_toolbox_defaults'
% command is either 'init' or 'load'
% parent is a handle to the gui that calls this gui, useful
% for updating the UserData field of the parent from this gui.
% The p structure is returned to the parent when the parent
% handle is given.
%

% $Revision: 1.1 $ $Date: 2009-04-28 22:13:56 $

% Licence:  GNU GPL, no express or implied warranties
% History:  01/2002, Darren.Weber_at_radiology.ucsf.edu
%           08/2002, Darren.Weber_at_radiology.ucsf.edu
%                    added EMSE avg handling
%                    added interpolation of zero point option
%           10/2003, Darren.Weber_at_radiology.ucsf.edu
%                    created gui_avg_open and adapted this
%                    function to handle CNT/EEG data formats
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if ~exist('p','var'),
 [p] = eeg_toolbox_defaults;
elseif isempty(p),
 [p] = eeg_toolbox_defaults;
end

if ~exist('command','var'), command = 'init'; end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Paint the GUI
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

switch command,

  case 'init',

    if exist('parent','var'),
      EEGOpen = INIT(p,parent);
    else
      EEGOpen = INIT(p,'');
    end

  case 'plot',

    EEGOpen = get(gcbf,'Userdata');

    EEGOpen.p = cnt_open(EEGOpen.p,EEGOpen.gui);
    set(EEGOpen.gui,'Userdata',EEGOpen); % update GUI with CNT data

   [p] = gui_updateparent(EEGOpen,0);

    if isequal(get(EEGOpen.handles.Bhold,'Value'),0),
      close gcbf;
      if isfield(EEGOpen,'parent'),
        parent = EEGOpen.parent.gui;
      else
        parent = [];
      end
    else
      parent = EEGOpen.gui;
    end

    plotfig = figure('Name',EEGOpen.p.cnt.file,...
      'NumberTitle','off',...
      'UserData',EEGOpen.p);
    movegui(plotfig,'center');

    plot(EEGOpen.p.cnt.timeArray,EEGOpen.p.cnt.data); axis tight;
    eeg_plot_metric;

    if isempty(parent), [Xpoint,Ypoint] = eeg_crosshair('init',EEGOpen.p);
    else                [Xpoint,Ypoint] = eeg_crosshair('init',EEGOpen.p,parent);
    end

  case 'save',

    fprintf('\nGUI_EEG_OPEN: Save As not implemented yet.\n');

  case 'return',

    EEGOpen = get(gcbf,'Userdata');

    set(EEGOpen.gui,'Pointer','watch');

    EEGOpen.p = cnt_open(EEGOpen.p);

    set(EEGOpen.gui,'Pointer','arrow');

    if isequal(get(EEGOpen.handles.Bhold,'Value'),1),
     [p] = gui_updateparent(EEGOpen,0);
    else
     [p] = gui_updateparent(EEGOpen);
      close gcbf;
    end

  otherwise,

    EEGOpen = get(gcbf,'Userdata');
    GUI.parent = EEGOpen.parent;
    gui_updateparent(GUI);
    close gcbf;

end

return

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [EEGOpen] = INIT(p,parent)
% GUI General Parameters

GUIwidth  = 500;
GUIheight = 120;

version = '$Revision: 1.1 $';
name = sprintf('EEG File Open [v %s]\n',version(11:15));

GUI = figure('Name',name,'Tag','EEG_OPEN',...
  'NumberTitle','off',...
  'MenuBar','none','Position',[1 1 GUIwidth GUIheight]);
movegui(GUI,'center');

Font.FontName   = 'Helvetica';
Font.FontUnits  = 'Pixels';
Font.FontSize   = 12;
Font.FontWeight = 'normal';
Font.FontAngle  = 'normal';

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CNT Data Selection and Parameters

G.Title_data = uicontrol('Parent',GUI,'Style','text','Units','Normalized',Font, ...
  'Position',[.01 .75 .17 .2],...
  'String','Data Type:','HorizontalAlignment','left');

switch lower(p.cnt.type),
  case 'scan4x_cnt',  cntType = 1;
  case 'scan3x_cnt',  cntType = 2;
  otherwise,          cntType = 1;
end

%  'String',{'ASCII_CNT' 'Scan4x_CNT' 'Scan3x_CNT' 'EEGLAB'},'Value',cntType,...

G.PcntType = uicontrol('Tag','PcntType','Parent',GUI,'Style','popupmenu',...
  'Units','Normalized',Font,  ...
  'Position',[.20 .75 .2 .2],...
  'String',{'scan4x_cnt' 'scan3x_cnt'},'Value',cntType,...
  'Callback',strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'EEGOpen.p.cnt.type = popupstr(EEGOpen.handles.PcntType);',...
  'set(gcbf,''Userdata'',EEGOpen); clear EEGOpen;'));

G.Title_path = uicontrol('Parent',GUI,'Style','text','Units','Normalized',Font, ...
  'Position',[.01 .50 .17 .2],...
  'String','Path','HorizontalAlignment','left');
G.EcntPath = uicontrol('Parent',GUI,'Style','edit','Units','Normalized',Font,  ...
  'Position',[.20 .50 .58 .2], 'String',p.cnt.path,...
  'Callback',strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'EEGOpen.p.cnt.path = get(EEGOpen.handles.EcntPath,''String'');',...
  'set(gcbf,''Userdata'',EEGOpen); clear EEGOpen;'));

G.Title_file = uicontrol('Parent',GUI,'Style','text','Units','Normalized',Font, ...
  'Position',[.01 .25 .17 .2],...
  'String','File','HorizontalAlignment','left');
G.EcntFile = uicontrol('Parent',GUI,'Style','edit','Units','Normalized',Font,  ...
  'Position',[.20 .25 .58 .2], 'String',p.cnt.file,...
  'Callback',strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'EEGOpen.p.cnt.file = get(EEGOpen.handles.EcntFile,''String'');',...
  'set(gcbf,''Userdata'',EEGOpen); clear EEGOpen;'));

Font.FontWeight = 'bold';

% BROWSE: Look for the data
browsecommand = strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'cd(EEGOpen.p.cnt.path);',...
  '[file, path] = uigetfile(',...
  '{''*.cnt'', ''NeuroScan (*.cnt)'';', ...
  ' ''*.*'',   ''All Files (*.*)''},', ...
  '''Select EEG File'');',...
  'if ~isequal(path,0), EEGOpen.p.cnt.path = path; end;',...
  'if ~isequal(file,0), EEGOpen.p.cnt.file = file; end;',...
  'set(EEGOpen.handles.EcntPath,''String'',EEGOpen.p.cnt.path);',...
  'set(EEGOpen.handles.EcntFile,''String'',EEGOpen.p.cnt.file);',...
  'set(gcbf,''Userdata'',EEGOpen); clear EEGOpen file path;');
G.BcntFile = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized',Font, ...
  'Position',[.01 .01 .17 .2], 'String','BROWSE',...
  'BackgroundColor',[0.8 0.8 0.0],...
  'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
  'Callback', browsecommand );

% PLOT: Load & plot the data!
G.Bplot = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
  'Position',[.20 .01 .18 .2],...
  'String','PLOT','BusyAction','queue',...
  'TooltipString','Plot the EEG data and return p struct.',...
  'BackgroundColor',[0.0 0.5 0.0],...
  'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
  'Callback',strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'p = gui_eeg_open(EEGOpen.p,''plot'');',...
  'clear EEGOpen;'));

% Save As
G.Bsave = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
  'Position',[.40 .01 .18 .2],'HorizontalAlignment', 'center',...
  'String','SAVE AS','TooltipString','EEG File Conversion Tool (not implemented yet)',...
  'BusyAction','queue',...
  'Visible','off',...
  'BackgroundColor',[0.0 0.0 0.75],...
  'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
  'Callback',strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'p = gui_eeg_open(EEGOpen.p,''save'');',...
  'clear EEGOpen;'));

% Quit, return file parameters
G.Breturn = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
  'Position',[.60 .01 .18 .2],...
  'String','RETURN','BusyAction','queue',...
  'TooltipString','Return p struct to workspace and parent GUI.',...
  'BackgroundColor',[0.75 0.0 0.0],...
  'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
  'Callback',strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'p = gui_eeg_open(EEGOpen.p,''return'');',...
  'clear EEGOpen;'));

% Cancel
G.Bcancel = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
  'Position',[.80 .01 .18 .2],...
  'String','CANCEL','BusyAction','queue',...
  'TooltipString','Close, do not return parameters.',...
  'BackgroundColor',[0.75 0.0 0.0],...
  'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
  'Callback',strcat('EEGOpen = get(gcbf,''Userdata'');',...
  'p = gui_eeg_open(EEGOpen.p,''cancel'');',...
  'clear EEGOpen;'));

% Hold GUI Open checkbox
G.Bhold = uicontrol('Parent',GUI,'Style','checkbox','Units','Normalized', Font, ...
  'Position',[.80 .25 .18 .2],'String','Hold GUI','BusyAction','queue',...
  'TooltipString','EEG File Load GUI remains open after ''Plot'' or ''Return'' commands.',...
  'Value',p.hold,'HorizontalAlignment', 'center');

% Store userdata
if exist('parent','var'), EEGOpen.parent.gui = parent; end
EEGOpen.gui = GUI;
EEGOpen.handles = G;
EEGOpen.p = p;
set(GUI,'Userdata',EEGOpen);
set(GUI,'HandleVisibility','callback');

return


classdef ShapePrinter < CompositeResultsPrinter

    methods (Access = public)

        function obj = ShapePrinter(d)
            obj.init(d);
        end

    end

    methods (Access = protected)

        function storeFieldsToPrint(obj,d)
            for iF = 1:numel(d.fieldToPrint)
                d.fields = d.fieldToPrint{iF}.value;
                obj.printers{iF}.storeFieldsToPrint(d)
            end
        end

        function createHeadPrinter(obj,d,dh)
            for iP = 1:numel(obj.printers)
              p = obj.printers{iP};
              hasGauss(iP) = p.getHasGaussData;
            end
            hasGauss = find(hasGauss);
            firstPrinterWithGauss = obj.printers{hasGauss(1)};
            p = firstPrinterWithGauss;
            p.createHeadPrinter(d,dh);
            h = p.getHeadPrinter();
            obj.headPrinter = h;
        end

        function createPrinters(obj,d)
            for iF = 1:numel(d.fieldToPrint)
                type = d.fieldToPrint{iF}.type;
                d.name = d.fieldToPrint{iF}.name;
                obj.printers{iF} = ResultsPrinter.create(type,d);
            end
        end

    end

end


function set_font_type(font)
%SET_FONT_TYPE sets the figures font type
%
%   Usage: set_font_type(font)
%
%   Input parameters:
%       font   - font type name
%
%   See also: set_font_size, print_png

%*****************************************************************************
% The MIT License (MIT)                                                      *
%                                                                            *
% Copyright (c) 2010-2019 SFS Toolbox Developers                             *
%                                                                            *
% Permission is hereby granted,  free of charge,  to any person  obtaining a *
% copy of this software and associated documentation files (the "Software"), *
% to deal in the Software without  restriction, including without limitation *
% the rights  to use, copy, modify, merge,  publish, distribute, sublicense, *
% and/or  sell copies of  the Software,  and to permit  persons to whom  the *
% Software is furnished to do so, subject to the following conditions:       *
%                                                                            *
% The above copyright notice and this permission notice shall be included in *
% all copies or substantial portions of the Software.                        *
%                                                                            *
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
% IMPLIED, INCLUDING BUT  NOT LIMITED TO THE  WARRANTIES OF MERCHANTABILITY, *
% FITNESS  FOR A PARTICULAR  PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL *
% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
% LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT  OR OTHERWISE, ARISING *
% FROM,  OUT OF  OR IN  CONNECTION  WITH THE  SOFTWARE OR  THE USE  OR OTHER *
% DEALINGS IN THE SOFTWARE.                                                  *
%                                                                            *
% The SFS Toolbox  allows to simulate and  investigate sound field synthesis *
% methods like wave field synthesis or higher order ambisonics.              *
%                                                                            *
% https://sfs.readthedocs.io                            sfstoolbox@gmail.com *
%*****************************************************************************

%% ===== Checking of input  parameters ==================================
nargmin = 1;
nargmax = 1;
narginchk(nargmin,nargmax);
isargchar(font)

%% ===== Apply settings ==================================================
% Get handle for active figure
h=gca;
% Set the font type for the axis tics
set(h,'FontName',font);
% set the font type for all text strings
set(findall(h,'type','text'),'FontName',font);
% FIXME: the following produces an segmentation fault under Octave
% Set the font type for colorbar tics
%h=colorbar;
%set(h,'FontName',font);


function name = p07_name ( )

%*****************************************************************************80
%
%% P07_NAME returns the name of problem 07.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string NAME, the name of the problem.
%
  name = 'DR4062';

  return
end


function str = cell2str(theCell)
% CELL2STR - Convert 1-D cells to a string
%
%   STR = CELL2STR(THECELL)
%
% Converts a 1-D cell to a string.
%
% Example:
%   A = {'test','test2','test3'};
%   str = cell2str(A)
%
%       produced str =
%    '{ 'test','test2','test3' }'
%
 %1-dim cells only, only chars and matricies

if isempty(theCell), str = '{}'; return; end;

str = '{ ';
for i=1:length(theCell),
        if ischar(theCell{i})
                str = [str '''' theCell{i} ''', '];
        elseif isnumeric(theCell{i}),
                str = [str mat2str(theCell{i}) ', '];
        end;
end;
str = [str(1:end-2) ' }'];


function p = problem( x )
p = x.problem_;

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function camBfloat2PDB(bfloat_filename,pdb_filename,ctr_filename,fa_filename)

opt_ctr = [' -i ' ctr_filename];
opt_bfloat = [' ' bfloat_filename];
opt_pdb = [' -p ' pdb_filename];

if ~exist(ctr_filename,'file') && exist(fa_filename,'file')
    % Create contrack parameters script if it doesn't exist
    % Bfloat conversion currently uses contrack so we need ctr file
    ctr = ctrCreate();
    % Must set pdb image, but can be anything
    % XXX
    % Must be absolute pathway or something is going wrong with relative
    % naming
    % XXX
    [pathstr, name, ext] = fileparts(fa_filename);
    ctr.pdf_filename = [name ext];
    ctr.image_directory = [pathstr '/'];
    ctrSave(ctr,ctr_filename);

end

cmd = ['contrack_score.glxa64' opt_ctr opt_pdb '  --thresh 100000 --seq --bfloat_no_stats' opt_bfloat];
display(cmd);
system(cmd,'-echo');

end


classdef ( Hidden ) Divider < matlab.mixin.SetGet
    %uix.Divider  Draggable divider
    %
    %  d = uix.Divider() creates a divider.
    %
    %  d = uix.Divider(p1,v1,p2,v2,...) creates a divider and sets
    %  specified property p1 to value v1, etc.

    %  Copyright 2009-2016 The MathWorks, Inc.
    %  $Revision: 1601 $ $Date: 2018-05-01 10:22:53 +0100 (Tue, 01 May 2018) $

    properties( Dependent )
        Parent % parent
        Units % units [inches|centimeters|characters|normalized|points|pixels]
        Position % position
        Visible % visible [on|off]
        BackgroundColor % background color [RGB]
        HighlightColor % border highlight color [RGB]
        ShadowColor % border shadow color [RGB]
        Orientation % orientation [vertical|horizontal]
        Markings % markings [pixels]
    end

    properties( Access = private )
        Control % uicontrol
        BackgroundColor_ = get( 0, 'DefaultUicontrolBackgroundColor' ) % backing for BackgroundColor
        HighlightColor_ = [1 1 1] % backing for HighlightColor
        ShadowColor_ = [0.7 0.7 0.7] % backing for ShadowColor
        Orientation_ = 'vertical' % backing for Orientation
        Markings_ = zeros( [0 1] ) % backing for Markings
        SizeChangedListener % listener
    end

    methods

        function obj = Divider( varargin )
            %uix.Divider  Draggable divider
            %
            %  d = uix.Divider() creates a divider.
            %
            %  d = uix.Divider(p1,v1,p2,v2,...) creates a dividerand sets
            %  specified property p1 to value v1, etc.

            % Create control
            control = matlab.ui.control.UIControl( ...
                'Style', 'checkbox', 'Internal', true, ...
                'Enable', 'inactive', 'DeleteFcn', @obj.onDeleted,...
                'Tag', 'uix.Divider' );

            % Store control
            obj.Control = control;

            % Set properties
            try
                uix.set( obj, varargin{:} )
            catch e
                delete( obj )
                e.throwAsCaller()
            end

            % Force update
            obj.update()

            % Create listener
            sizeChangedListener = event.listener( control, 'SizeChanged', ...
                @obj.onSizeChanged );

            % Store listener
            obj.SizeChangedListener = sizeChangedListener;

        end % constructor

        function delete( obj )
            %delete  Destructor

            control = obj.Control;
            if isgraphics( control ) && strcmp( control.BeingDeleted, 'off' )
                delete( control )
            end

        end % destructor

    end % structors

    methods

        function value = get.Parent( obj )

            value = obj.Control.Parent;

        end % get.Parent

        function set.Parent( obj, value )

            obj.Control.Parent = value;

        end % set.Parent

        function value = get.Units( obj )

            value = obj.Control.Units;

        end % get.Units

        function set.Units( obj, value )

            obj.Control.Units = value;

        end % set.Units

        function value = get.Position( obj )

            value = obj.Control.Position;

        end % get.Position

        function set.Position( obj, value )

            obj.Control.Position = value;

        end % set.Position

        function value = get.Visible( obj )

            value = obj.Control.Visible;

        end % get.Visible

        function set.Visible( obj, value )

            obj.Control.Visible = value;

        end % set.Visible

        function value = get.BackgroundColor( obj )

            value = obj.BackgroundColor_;

        end % get.BackgroundColor

        function set.BackgroundColor( obj, value )

            % Check
            assert( isa( value, 'double' ) && ...
                isequal( size( value ), [1 3] ) && ...
                all( value >= 0 ) && all( value <= 1 ), ...
                'uix:InvalidArgument', ...
                'Property ''BackgroundColor'' must be a valid colorspec.' )

            % Set
            obj.BackgroundColor_ = value;

            % Update
            obj.update()

        end % set.BackgroundColor

        function value = get.HighlightColor( obj )

            value = obj.HighlightColor_;

        end % get.HighlightColor

        function set.HighlightColor( obj, value )

            % Check
            assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ...
                all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ...
                'uix:InvalidPropertyValue', ...
                'Property ''HighlightColor'' must be an RGB triple.' )

            % Set
            obj.HighlightColor_ = value;

            % Update
            obj.update()

        end % set.HighlightColor

        function value = get.ShadowColor( obj )

            value = obj.ShadowColor_;

        end % get.ShadowColor

        function set.ShadowColor( obj, value )

            % Check
            assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ...
                all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ...
                'uix:InvalidPropertyValue', ...
                'Property ''ShadowColor'' must be an RGB triple.' )

            % Set
            obj.ShadowColor_ = value;

            % Update
            obj.update()

        end % set.ShadowColor

        function value = get.Orientation( obj )

            value = obj.Orientation_;

        end % get.Orientation

        function set.Orientation( obj, value )

            % Check
            assert( ischar( value ) && ismember( value, ...
                {'horizontal','vertical'} ) )

            % Set
            obj.Orientation_ = value;

            % Update
            obj.update()

        end % set.Orientation

        function value = get.Markings( obj )

            value = obj.Markings_;

        end % get.Markings

        function set.Markings( obj, value )

            % Check
            assert( isa( value, 'double' ) && ndims( value ) == 2 && ...
                size( value, 2 ) == 1 && all( isreal( value ) ) && ...
                all( ~isinf( value ) ) && all( ~isnan( value ) ) && ...
                all( value > 0 ), 'uix:InvalidPropertyValue', ...
                'Property ''Markings'' must be a vector of positive values.' ) %#ok<ISMAT>

            % Set
            obj.Markings_ = value;

            % Update
            obj.update()

        end % set.Markings

    end % accessors

    methods

        function tf = isMouseOver( obj, eventData )
            %isMouseOver  Test for mouse over
            %
            %  tf = d.isMouseOver(wmd) tests whether the WindowMouseData
            %  wmd is consistent with the mouse pointer being over the
            %  divider d.
            %
            %  This method returns false for dividers that are being
            %  deleted.

            tf = isvalid( obj ); % initialize
            for ii = 1:numel( obj )
                tf(ii) = tf(ii) && obj(ii).Control == eventData.HitObject;
            end

        end % isMouseOver

    end % methods

    methods( Access = private )

        function onDeleted( obj, ~, ~ )
            %onDeleted  Event handler

            % Call destructor
            obj.delete()

        end % onDeleted

        function onSizeChanged( obj, ~, ~ )
            %onSizeChanged  Event handler

            % Update
            obj.update()

        end % onSizeChanged

    end % event handlers

    methods( Access = private )

        function update( obj )
            %update  Update divider
            %
            %  d.update() updates the divider markings.

            % Get properties
            control = obj.Control;
            position = control.Position;
            backgroundColor = obj.BackgroundColor;
            highlightColor = obj.HighlightColor;
            shadowColor = obj.ShadowColor;
            orientation = obj.Orientation;
            markings = obj.Markings;

            % Assemble mask
            mask = zeros( floor( position([4 3]) ) - [1 1] ); % initialize
            switch orientation
                case 'vertical'
                    markings(markings < 4) = [];
                    markings(markings > position(4)-6) = [];
                    for ii = 1:numel( markings )
                        marking = markings(ii);
                        mask(floor( marking ) + [-3 0 3],1:end-1) = 1;
                        mask(floor( marking ) + [-2 1 4],1:end-1) = 2;
                    end
                case 'horizontal'
                    markings(markings < 4) = [];
                    markings(markings > position(3)-6) = [];
                    for ii = 1:numel( markings )
                        marking = markings(ii);
                        mask(2:end,floor( marking ) + [-3 0 3]) = 1;
                        mask(2:end,floor( marking ) + [-2 1 4]) = 2;
                    end
            end

            % Assemble color data
            cData1 = repmat( backgroundColor(1), size( mask ) );
            cData1(mask==1) = highlightColor(1);
            cData1(mask==2) = shadowColor(1);
            cData2 = repmat( backgroundColor(2), size( mask ) );
            cData2(mask==1) = highlightColor(2);
            cData2(mask==2) = shadowColor(2);
            cData3 = repmat( backgroundColor(3), size( mask ) );
            cData3(mask==1) = highlightColor(3);
            cData3(mask==2) = shadowColor(3);
            cData = cat( 3, cData1, cData2, cData3 );

            % Set properties
            control.ForegroundColor = backgroundColor;
            control.BackgroundColor = backgroundColor;
            control.CData = cData;

        end % update

    end % methods

end % classdef


function fileNames = list_image_files(parameterString)

if nargin==0,
    %clc; clear;
    parameterString = '.';
end

temp = dir(parameterString);
fileNames = {};
[fileNames{1:length(temp),1}] = deal(temp.name);

% Find hidden files.
hiddenFiles = nan(size(fileNames));
for fileIndex = 1:length(fileNames),
    tempName = fileNames{fileIndex};
    hiddenFiles(fileIndex) = tempName(1) == '.';
end

% Find which entries in the listing are images.
imageFlags = nan(size(fileNames));
for fileIndex = 1:length(fileNames),
    [boo1, boo2, tempExtension] = fileparts(fileNames{fileIndex});
    tempExtension = lower(tempExtension);
    imageFlags(fileIndex) = ismember(tempExtension, {'.bmp', '.png', '.tif', '.jpg'});
end

% Find which entries in the listing are directories.
directoryFlags = {};
[directoryFlags{1:length(temp),1}] = deal(temp.isdir);
directoryFlags = cell2mat(directoryFlags);

tempFlags = (~hiddenFiles) & (~directoryFlags) & (imageFlags);
fileNames = fileNames(tempFlags);


function varargout = legendflex(varargin)
%LEGENDFLEX Creates a more flexible legend
%
% legendflex(M, param1, val1, ...)
% legendflex(h, M, param1, val1, ...)
% [legend_h,object_h,plot_h,text_str] = legendflex(...)
%
% This offers a more flexible version of the legend command.  It offers a
% different method of positioning the legend, as well as options to:
%
%   - organize legend text and symbols in a grid with a specified number of
%     rows and/or columns
%   - rescale the horizontal space used by each legend symbol
%   - create multiple legends for the same axis
%   - add a title to the legend within the legend box
%
% Unlike in the default legend command, where the legend is positioned
% relative to the labeled objects' parent axis according to one of 16
% location strings, this function positions the legend based on two anchor
% points (one on either the figure or a child object of a figure, and one
% on the legend itself) and a buffer (or offset) between these two anchor
% points. The anchor points refer to the corners and centers of each
% side of the box surrounding the reference object and the legend itself;
% they can be refered to either as numbers (1-8, clockwise from northwest
% corner) or strings ('nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w').  The
% position of the legend is determined by these two points and the distance
% between them, defined in the 'buffer' variable, which by default is
% measured in pixels.  So the combination of
%
%  (..., 'ref', gca, 'anchor', [3 3], 'buffer', [-10 -10])
%
% means that you want the northeast corner of the current axis to be
% aligned with the northeast corner of the legend, but with the legend
% shifted 10 pixels to the left and down.
%
% This method of positioning can be particularly useful when labeling a
% figure that includes many subplots that share a common color scheme,
% where the "best" location for a legend is not necessarily within the
% bounds of an axis.  Unlike the legend command, the axes in the figure are
% never resized (and it is up to the user to check that the legend fits on
% the figure in the specified location).  In addition to being easier than
% manually positioning a legend, this function updates the legend location
% when the figure is resized, preserving the desired alignment.  The
% following anchor/buffer combinations, when used with the default
% reference and a buffer unit of pixels, approximately replicate the
% typical legend locations:
%
% Specifier              Anchor    Buffer
%
% north                  [2 2]     [  0 -10]
% south                  [6 6]     [  0  10]
% east                   [4 4]     [-10   0]
% west                   [8 8]     [ 10   0]
% northeast              [3 3]     [-10 -10]
% northwest              [1 1]     [ 10 -10]
% southeast              [5 5]     [-10  10]
% southwest              [7 7]     [ 10  10]
% northoutside*          [2 6]     [  0  10]
% southoutside*          [6 2]     [  0 -10]
% eastoutside*           [3 8]     [ 10   0]
% westoutside*           [8 3]     [-10   0]
% northeastoutside*      [3 1]     [ 10   0]
% northwestoutside*      [1 3]     [-10   0]
% southeastoutside*      [5 7]     [ 10   0]
% southwestoutside*      [7 5]     [-10   0]  *placed outside axis rather
%                                              than resizing plot box
%
% This function should support all types of plot objects.
%
% Updates to labeled line and patch properties should be reflected in the
% legend.  In pre-R2014b versions of Matlab (those that use the old
% non-object graphics handles), properties of more complex legend labels,
% such as contours, quivers, bars, etc.) will also be synced to the legend;
% however, at this time, the code doesn't update properties for anything
% other than lines and patches in R2014b+ (haven't found a good way to
% listen for changes to the properties of the other graphics object types).
%
% A note on resizing: This function assigns a resize function to the parent
% figure to maintain the position of the legend (in terms of anchor
% location and buffer) as the figure size changes.  If you manually resize
% the legend, this function will respect changes to height, width, and
% units (though I don't recommend changing the units to 'normalized', as
% this can cause the text and symbols to overflow the legend box on
% resize).  It will not respect manual repositioning when resizing, since
% it assumes you want to maintain the anchor/buffer prescription used to
% create it.  Overall, I've tried to make this resize as unobtrusive as
% possible; if your figure already has a resize function at the time you
% apply it, that behavior is inherited, with the legend-resize called
% afterward.  If you plan to further modify the figure's resize function
% post-legendflex and want to maintain repositioning of the legends,
% retrieve the resize function via hfun = get(hfig, 'ResizeFcn'), pass it
% to the new resize function, and invoke it via feval(oldfun, h, ed), where
% h and ed are the default variables passed by a callback function.
%
% Input variables:
%
%   M:          cell array of strings, labels for legend
%
%   h:          handle of axis or handle(s) of object(s) to be labeled.  If
%               this is an axis handle, all children of the axis will be
%               included in the legend.  If not included, current axis is
%               used.
%
% Optional input variables (passed as parameter/value pairs): [default]
%
%   ncol:       number of columns, or 0 to indicate as many as necessary
%               given the # of labeled objects [1 if nrow is 0, 0
%               otherwise]
%
%   nrow:       number of rows, or 0 to indicate as many as necessary
%               given the # of labeled objects [0]
%
%   ref:        handle of object used to position the legend. This can be
%               either a figure or a child object of a figure (and does not
%               need to relate in any way to the objects being labeled).
%               If not included, the reference will be to the axis that a
%               normal legend would be associated with (usually the parent
%               axis of the labeled objects, unless objects from multiple
%               axes are passed, in which case it's the parent object of
%               the first labeled object).
%
%   anchor:     1 x 2 array specifying which points of the reference object
%               and new legend, respectively, to anchor to each other.
%               Anchor points can be described using either numbers (in a 1
%               x 2 double array) or directional strings (in a 1 x 2 cell
%               array) as follows:
%               1:  'nw'    upper left corner
%               2:  'n'     center of top edge
%               3:  'ne'    upper right corner
%               4:  'e'     center of right edge
%               5:  'se'    bottom right corner
%               6:  's'     center of bottom edge
%               7:  'sw'    bottom left corner
%               8:  'w'     center of left edge
%
%               [[3 3], i.e. {'ne' 'ne'}]
%
%   buffer:     1 x 2 array of horizontal and vertical distance,
%               respectively, from the reference anchor point to the legend
%               anchor point. Distance is measured in units specified by
%               bufferunit. [[-10 -10]]
%
%   bufferunit: unit for buffer distance.  Note that this property only
%               affects the units used to position the legend, not the
%               units for the legend itself (which is always a fixed size,
%               based on the space needed to encapsulate the specified
%               symbols and text).  The 'normalized' units are normalized
%               to size of the figure. ['pixels']
%
%   box:        'on' or 'off', specifies whether to enclose legend objects
%               in a box ['on']
%
%   xscale:     scalar value indicating scale factor to apply to the width
%               required by each symbol, relative to the size used by
%               legend. For example, 0.5 will shorten the lines/patches by
%               half. [1]
%
%   title:      A title string to be added inside the legend box, centered,
%               above all legend entries.  This can be either a string or a
%               cell array of strings; the latter will produce a multi-line
%               title. If empty, no title is added.  ['']
%
%   padding:    1 x 3 array, pixel spacing added to beginning of each
%               column (before symbol), between symbol and text, and after
%               text, respectively.  Usually, the default provides the
%               spacing typical of a regular legend, but occassionally the
%               extent properties wrap a little too close to text, making
%               things look crowded; in these cases you can try unsquishing
%               (or squishing, via use of negative values) things via this
%               parameter. [2 1 1]
%
%   nolisten:   logical scalar.  If true, don't add the event listeners.
%               The event listeners update the legend objects when you
%               change a property of the labeled objects (such as line
%               style, color, etc.).  However, the updating requires the
%               legend to be redrawn, which can really slow things down,
%               especially if you're labelling lots of objects that get
%               changed together (if you change the line width of 100
%               labeled lines, the legend gets redrawn 100 times).  In more
%               recent releases, this also occurs when printing to file, so
%               I recommend setting this to true if you plan to print a
%               legend with a large number of labeled objects.  The legend
%               will still be redrawn on figure resize regardless of the
%               value of this parameter. [false]
%
%   In addition to these legendflex-specific parameters, this function will
%   accept any parameter accepted by the original legend function (e.g.
%   font properties) except 'location', 'boxon', 'boxoff', or 'hide'.
%
% Output variables:
%
%   legend_h:   handle of the legend axis.  It is not linked to an axis or
%               graphics objects in the same way as a Matlab legend.
%               However, on figure resize, all properties of the legend
%               objects are checked for changes, so adjusting the figure
%               size can re-link the legend to the labeled objects after
%               you have made changes to those objects.
%
%   object_h:   handles of the line, patch, and text graphics objects
%               created in the legend
%
%   plot_h:     handles of the lines and other objects labeled in this
%               legend
%
%   text_str:   cell array of the text strings used in the legend
%
%
% Example:
%
% % Replicating an example from legend.m:
%
% figure;
% b = bar(rand(10,5),'stacked'); colormap(summer); hold on
% x = plot(1:10,5*rand(10,1),'marker','square','markersize',12,...
%          'markeredgecolor','y','markerfacecolor',[.6 0 .6],...
%          'linestyle','-','color','r','linewidth',2); hold off
% lbl = {'Carrots','Peas','Peppers','Green Beans','Cucumbers','Eggplant'};
%
% % Rather than covering up data or resizing the axis, let's squeeze the
% % legend into the margin at the top of the figure;
%
% legendflex([b,x], lbl, 'ref', gcf, ...
%                        'anchor', {'n','n'}, ...
%                        'buffer',[0 0], ...
%                        'nrow',2, ...
%                        'fontsize',8);

% Copyright 2011-2014 Kelly Kearney

% Detemine whether HG2 is in use

hg2flag = ~verLessThan('matlab', '8.4.0');
r2016aflag = ~verLessThan('matlab', '9.0.0');
r2013bflag = ~verLessThan('matlab', '8.2.0');

%-------------------
% Parse input
%-------------------
%
% allinput = varargin; % Save for callback later
%
% islegin = false(size(varargin));

% First inputs must be either:
% (M, ...)
% (h, M, ...)

narginchk(1,Inf);

% Split input into the variables that will be passed to legend (handles and
% labels) and everything else

handlepassed = all(ishandle(varargin{1})); % for HG1/HG2

iscellstr = @(x) cellfun(@(y) ischar(y), x); % For now...
% iscellstr = @(x) cellfun(...
%     @(y) ischar(y) || (iscell(y) && all(cellfun(@ischar,y))), x); % for multi-line?

if handlepassed
    legin = varargin(1:2);
    if ~iscell(legin{2}) || ~all(iscellstr(legin{2}))
        error('Legend labels must be a cell array of strings');
    end
    pv = varargin(3:end);
else
    legin = varargin(1);
    if ~iscell(legin{1}) || ~all(iscellstr(legin{1}))
        if isnumeric(legin{1})
            error('Unable to parse input 1; check that handle(s) exist');
        else
            error('Legend labels must be a cell array of strings');
        end
    end
    pv = varargin(2:end);
end

% Parse my optional properties

if hg2flag
    defref = gobjects(0);
else
    defref = NaN;
end

if r2013bflag
    addParamMethod = 'addParameter';
else
    addParamMethod = 'addParamValue';
end

p = inputParser;
p.(addParamMethod)('xscale',     1,         @(x) validateattributes(x, {'numeric'}, {'nonnegative','scalar'}));
p.(addParamMethod)('ncol',       0,         @(x) validateattributes(x, {'numeric'}, {'scalar', 'integer'}));
p.(addParamMethod)('nrow',       0,         @(x) validateattributes(x, {'numeric'}, {'scalar', 'integer'}));
p.(addParamMethod)('ref',        defref,    @(x) validateattributes(x, {'numeric','handle'}, {'scalar'}));
p.(addParamMethod)('anchor',     [3 3],     @(x) validateattributes(x, {'numeric','cell'}, {'size', [1 2]}));
p.(addParamMethod)('buffer',     [-10 -10], @(x) validateattributes(x, {'numeric'}, {'size', [1 2]}));
p.(addParamMethod)('bufferunit', 'pixels',  @(x) validateattributes(x, {'char'}, {}));
p.(addParamMethod)('box',        'on',      @(x) validateattributes(x, {'char'}, {}));
p.(addParamMethod)('title',      '',        @(x) validateattributes(x, {'char','cell'}, {}));
p.(addParamMethod)('padding',    [2 1 1],   @(x) validateattributes(x, {'numeric'}, {'size', [1 3]})); % 'nonnegative'
p.(addParamMethod)('nolisten',   false,     @(x) validateattributes(x, {'logical'}, {'scalar'}));
p.KeepUnmatched = true;

p.parse(pv{:});
Opt = p.Results;

% Any parameters that don't match mine are assumed to be a legend property.
%  If not, legend will handle the error when I call it.

Extra = p.Unmatched;
extra = [fieldnames(Extra) struct2cell(Extra)];
extra = extra';

% Validate that units and box inputs are correct

validatestring(Opt.bufferunit, {'pixels','normalized','inches','centimeters','points','characters'}, 'legendflex', 'bufferunit');
validatestring(Opt.box, {'on', 'off'}, 'legendflex', 'box');

% Translate anchor strings to numbers, if necessary

if iscell(Opt.anchor)
    [blah, Opt.anchor] = ismember(Opt.anchor, {'nw','n','ne','e','se','s','sw','w'});
    if ~all(blah)
        error('Anchor must be 1 x 2 cell array of strings: n, e, s, w, ne, nw, se, sw');
    end
else
    validateattributes(Opt.anchor, {'numeric'}, {'integer', '<=', 8}, 'legendflex', 'anchor');
end

% Create a temporary legend to get all the objects

S = warning('off', 'MATLAB:legend:PlotEmpty');
if r2016aflag
    % The new legend objects are pretty opaque... even diving into the
    % undocumented properties, I haven't been able to find the handles of
    % the legend sub-components (lines, text, etc).  So I need to stick to
    % the legacy version, which creates an axis object rather than legend
    % object. Legacy version has bug in text properties parsing, though, so
    % need to work around that too: use the new-style legend object to get
    % proper text properties, then use those to alter the buggy old-style
    % legend.
    tmp = legend(legin{:}, extra{:}, 'location', 'northeast');
    textProps = {'FontAngle','FontName','FontSize','FontUnits','FontWeight','Interpreter'};
    tprop = get(tmp, textProps);
    delete(tmp);
    wtmp = warning('off', 'MATLAB:handle_graphics:exceptions:SceneNode'); % silence Latex interpreter thing
    [h.leg, h.obj, h.labeledobj, h.textstr] = legend(legin{:}, extra{:}, 'location', 'northeast');
    warning(wtmp);
    nobj = length(h.labeledobj);
    for it = 1:length(textProps)
        set(h.obj(1:nobj), textProps{it}, tprop{it});
    end
else
    [h.leg, h.obj, h.labeledobj, h.textstr] = legend(legin{:}, extra{:}, 'location', 'northeast');
    nobj = length(h.labeledobj);
end
warning(S);

if nobj == 0
    warning('Plot empty; no legend created');
    return
end

% There's a bug in R2014b-R2015a that causes rendering issues if a contour
% object is included in a legend and legend is called with more than one
% output. For some reason, the rendering issues disappear only if the
% contour object(s) is listed last in the legend.  So for now, my
% workaround for this is to change the order of the legend labels as
% necessary.  Issue appears to be fixed in 2015b.

iscont = strcmp(get(h.labeledobj, 'type'), 'contour');
cbugflag = ~verLessThan('matlab', '8.4.0') && verLessThan('matlab', '8.6.0') && any(iscont);

if cbugflag

    if length(legin) == 1
        legin = {h.labeledobj legin{1}};
    end

    delete(h.leg);

    [srt, isrt] = sort(iscont);
    legin{1} = legin{1}(isrt);
    legin{2} = legin{2}(isrt);

    [h.leg, h.obj, h.labeledobj, h.textstr] = legend(legin{:}, extra{:}, 'location', 'northeast');

end

% # rows and columns

if (Opt.ncol == 0) && (Opt.nrow == 0)
    Opt.ncol = 1;
    Opt.nrow = nobj;
elseif (Opt.ncol == 0)
    Opt.ncol = ceil(nobj./Opt.nrow);
elseif (Opt.nrow == 0)
    Opt.nrow = ceil(nobj./Opt.ncol);
end
if Opt.ncol*Opt.nrow < nobj
    error('Number of legend entries greater than specified grid allows; change ncol and/or nrow');
end

% Reference object

if hg2flag

    if isempty(Opt.ref)

        if all(ishandle(legin{1}))
            tmp = ancestor(legin{1}, 'axes');
            if iscell(tmp)
                Opt.ref = tmp{1};
            else
                Opt.ref = tmp(1);
            end
        else
            Opt.ref = gca;
        end

    end
else
    if isnan(Opt.ref)
        tmp = get(h.leg, 'UserData');
        Opt.ref = tmp.PlotHandle;
    end
end
if ~ishandle(Opt.ref)
    error('Input ref must be a graphics handle');
end

% Box

Opt.box = strcmpi('on', Opt.box);

% Convert units to getpos abbreviations

unittable = {...
    'px'  'Pixels'
    'nz'  'Normalized'
    'in'  'Inches'
    'cm'  'Centimeters'
    'pt'  'Points'
    'ch'  'Characters'};
Opt.bufunit = unittable{strcmpi(unittable(:,2),Opt.bufferunit),1};

% Check for title

addtitle = ~isempty(Opt.title);

%-------------------
% New placement of
% everything in
% legend
%-------------------

% Determine parent figure

figh = ancestor(Opt.ref, 'figure');
currax = get(figh, 'currentaxes');

% Calculate row height

legpospx = getpos(h.leg, 'px');

% rowHeight = legpospx(4)/nobj;
vmarginNm =  0.275/nobj;
vmarginPx = legpospx(4) * vmarginNm;

rowHeightNm = (1 - vmarginNm)/nobj;
rowHeight = rowHeightNm .* legpospx(4);

% Determine width needed for each text string

if nobj == 1
    textExtent = get(h.obj(1:nobj), 'Extent');
else
    textExtent = cell2mat(get(h.obj(1:nobj), 'Extent'));
end
textWidthPx  = textExtent(:,3) .* legpospx(3);
textHeightPx = textExtent(:,4) .* legpospx(4);
textWidthNm = textExtent(:,3);

% Calculate horizontal space needed for symbols

symbolWidthPx = textExtent(1,1) .* legpospx(3) * Opt.xscale;
symbolWidthNm = textExtent(1,1);

% Calculate column width needed for 2px-symbol-1px-text-1px

colWidth = zeros(Opt.ncol*Opt.nrow,1);
colWidth(1:nobj) = textWidthPx + symbolWidthPx + sum(Opt.padding);
colWidth = reshape(colWidth, Opt.nrow, Opt.ncol);
colWidth = max(colWidth,[],1);

% If title is added, figure out how much space it will need

if addtitle
    textProps = {'FontAngle','FontName','FontSize','FontUnits','FontWeight','Interpreter'};
    textVals = get(h.obj(1), textProps);
    ttlprops = [textProps; textVals];

    fpos = getpos(figh, 'px');
    figtmp = figure('units','pixels','position',[0 0 fpos(3:4)],'visible','off');
    axes('parent',figtmp,'position',[0 0 1 1],'xlim',[0 fpos(3)],'ylim',[0 fpos(4)]);
    tmp = text(0,0,Opt.title, ttlprops{:}, 'horiz', 'left', 'vert', 'bottom');
    ttlex = get(tmp, 'extent');
    ttlwidth = ceil(ttlex(3)) + 4; % Add a little padding
    ttlheight = ceil(ttlex(4));

    if ttlwidth > sum(colWidth)
        colWidth(end) = colWidth(end) + (ttlwidth-sum(colWidth));
    end
    close(figtmp);
end

% Locate bottom left corner of each legend symbol, text box, and title

xsymbnew = [0 cumsum(colWidth(1:end-1))]+Opt.padding(1);
ysymbnew = (rowHeight*Opt.nrow + vmarginPx)-(1:Opt.nrow)*rowHeight;
[xsymbnew, ysymbnew] = meshgrid(xsymbnew, ysymbnew);
xsymbnew = xsymbnew(1:nobj);
ysymbnew = ysymbnew(1:nobj);

xtext = xsymbnew + Opt.padding(2) + symbolWidthPx;
ytext = ysymbnew;% + 1;

xsymbold = zeros(nobj,1);
ysymbold = 1 - (1/nobj)*(1:nobj);

wnewleg = sum(colWidth);
hnewleg = rowHeight*Opt.nrow + vmarginPx;

if addtitle
    xttl = wnewleg/2;
    yttl = hnewleg;
    hnewleg = hnewleg + ttlheight;
end

% Get legend position in bufferunit and translate to pixels

legpos = positionleg(Opt.ref, wnewleg, hnewleg, Opt.anchor, Opt.buffer, Opt.bufunit);
tmpax = axes('units', Opt.bufferunit, 'position', legpos,'visible','off');
legpos = getpos(tmpax, 'px');
delete(tmpax);

%-------------------
% Create legend
%-------------------

% Create the legend axis

hnew.leg = axes('units', 'pixels', ...
               'position', legpos, ...
               'xlim', [0 legpos(3)], ...
               'ylim', [0 legpos(4)], ...
               'xtick', [], ...
               'ytick', [], ...
               'box', 'on', ...
               'parent', figh);

% Copy the text strings to the new legend

textProps = {'FontAngle','FontName','FontSize','FontUnits','FontWeight','Interpreter','HorizontalAlignment','VerticalAlignment'};
textVals = get(h.obj(1:nobj), textProps);

if hg2flag
    hnew.obj = gobjects(size(h.obj));
else
    hnew.obj = zeros(size(h.obj));
end
for it = 1:nobj
    props = [textProps; textVals(it,:)];
    hnew.obj(it) = text(xtext(it), ytext(it), h.textstr{it}, props{:}, ...
                        'horizontalalignment', 'left', ...
                        'verticalalignment', 'bottom');
end

% Copy the symbols to the new legend

nsymbol = length(h.obj) - nobj;

for ii = 1:nsymbol

    if strcmp(get(h.obj(nobj+ii), 'type'), 'hggroup')

        tag = get(h.obj(nobj+ii),'Tag');
        if ~isempty(tag)
            [blah, idx] = ismember(tag,h.textstr);
        end

        chld = findall(h.obj(nobj+ii), 'type', 'line', '-or', 'type', 'patch');
        for ic = 1:length(chld)
            xy = get(chld(ic), {'xdata', 'ydata'});

            xnorm = xy{1}./symbolWidthNm;
            ynorm = (xy{2}- (1-idx*rowHeightNm))./rowHeightNm;

            xnew = xnorm * symbolWidthPx + xsymbnew(idx);
            ynew = ynorm * rowHeight     + ysymbnew(idx);

            set(chld(ic), 'xdata', xnew, 'ydata', ynew);
        end

        hnew.obj(nobj+ii) = copyobj(h.obj(nobj+ii), hnew.leg);

    else

        hnew.obj(nobj+ii) = copyobj(h.obj(nobj+ii), hnew.leg);

        tag = get(h.obj(nobj+ii),'Tag');
        if ~isempty(tag) % assumes empty tags indicate repetition of previous tag (true pre-2014b)
            [blah, idx] = ismember(tag,h.textstr);
        end

        xy = get(h.obj(nobj+ii), {'xdata', 'ydata'});

        xnorm = xy{1}./symbolWidthNm;
        ynorm = (xy{2}- (1-idx*rowHeightNm))./rowHeightNm;

        xnew = xnorm * symbolWidthPx + xsymbnew(idx);
        ynew = ynorm * rowHeight     + ysymbnew(idx);

        set(hnew.obj(nobj+ii), 'xdata', xnew, 'ydata', ynew);

    end

end

% Add title

if addtitle
    text(xttl, yttl, Opt.title, ttlprops{:}, 'horiz', 'center', 'vert', 'bottom');
end

% Add box or hide axis

if Opt.box
    set(hnew.leg, 'box', 'on');
else
    if hg2flag
        set(hnew.leg, 'box', 'off', 'color', 'none', 'xcolor', 'none', 'ycolor', 'none');
    else
        set(hnew.leg, 'visible', 'off');
    end
end

% Delete the temporary legend

delete(h.leg);

% Return focus to previously-current axis

set(figh, 'currentaxes', currax);
drawnow; % Not sure why this is necessary for the currentaxes to take effect, but it is

% Fix for vertical-alignment issue: This solution still isn't perfect, but
% it seems to help for most Interpreter-none and Interpreter-latex cases.
% The TeX interpreter still places sub- and superscripts too high/low... no
% robust fix found for that yet.
%
% TODO: need to add proper calcs for when title included
%
% Thanks to S�ren Enemark for this suggestion.

if ~addtitle
    try % TODO: Crashing on some edge cases
        textobj = hnew.obj(1:nobj);
        yheight = get(hnew.leg, 'ylim');
        yheight = yheight(2);

        ylo = get(textobj(Opt.nrow), 'extent');
        ylo = ylo(2);
        yhi = get(textobj(1), 'extent');
        yhi = sum(yhi([2 4]));
        dy = yheight/2 - 0.5*(ylo + yhi);
        for ii = 1:length(textobj)
            pos = get(textobj(ii), 'position');
            set(textobj(ii), 'position', pos + [0 dy 0]);
        end
    end
end

%-------------------
% Callbacks and
% listeners
%-------------------

% Save some relevant variables in the new legend axis's application data

Lf.ref        = Opt.ref;
Lf.w          = wnewleg;
Lf.h          = hnewleg;
Lf.anchor     = Opt.anchor;
Lf.buffer     = Opt.buffer;
Lf.bufunit    = Opt.bufunit;
Lf.bufferunit = Opt.bufferunit;
Lf.plotobj    = h.labeledobj;
Lf.legobj     = hnew.obj;

setappdata(hnew.leg, 'legflex', Lf);

% Resize listeners

addlistener(hnew.leg, 'Position', 'PostSet', @(src,evt) updatelegappdata(src,evt,hnew.leg));
if hg2flag && strcmp(Lf.ref.Type, 'figure')
    addlistener(Lf.ref, 'SizeChanged', @(src,evt) updatelegpos(src,evt,hnew.leg));
else
    addlistener(Lf.ref, 'Position', 'PostSet', @(src,evt) updatelegpos(src,evt,hnew.leg));
end
rsz = get(figh, 'ResizeFcn');
if isempty(rsz) % No previous resize function
    set(figh, 'ResizeFcn', @updatelegfigresize);
else
    if ~iscell(rsz)
        rsz = {rsz};
    end
    hasprev = cellfun(@(x) isequal(x, @updatelegfigresize), rsz);
    if ~hasprev
        rsz = {rsz{:} @updatelegfigresize};
        set(figh, 'ResizeFcn', {@wrapper, rsz});
    end
end

if ~Opt.nolisten

    % Run the resync function if anything changes with the labeled objects

    objwatch = findall(h.labeledobj, 'type', 'line', '-or', 'type', 'patch');

    for ii = 1:length(objwatch)
        switch lower(get(objwatch(ii), 'type'))
            case 'line'
                triggerprops = {'Color','LineStyle','LineWidth','Marker','MarkerSize','MarkerEdgeColor','MarkerFaceColor'};
                addlistener(objwatch(ii), triggerprops, 'PostSet', @(h,ed) resyncprops(h,ed,hnew.leg));
            case 'patch'
                triggerprops = {'CData','CDataMapping','EdgeAlpha','EdgeColor','FaceAlpha','FaceColor','LineStyle','LineWidth','Marker','MarkerEdgeColor','MarkerFaceColor','MarkerSize'};
                addlistener(objwatch(ii), triggerprops, 'PostSet', @(h,ed) resyncprops(h,ed,hnew.leg));
        end
    end

end

%-------------------
% Output
%-------------------

out = {hnew.leg, hnew.obj, h.labeledobj, h.textstr};
varargout = out(1:nargout);

%***** Subfunctions *****

%------------------------
% Position new legend
%------------------------

function legpos = positionleg(href, w, h, anchor, buffer, bufunit)
% ap: position vector for reference object
% lp: position vector for legend

if strcmp(get(href, 'type'), 'figure')
    tmp = axes('parent', href,'position', [0 0 1 1],'visible','off');
    pos = getpos(tmp, bufunit);
    delete(tmp);
else
    pos = getpos(href, bufunit);
end

htmp = axes('units', 'pixels', 'position', [0 0 w h], 'visible','off');
lpos = getpos(htmp, bufunit);
delete(htmp);
w = lpos(3);
h = lpos(4);

% Find anchor locations on reference object

refxy = [...
    pos(1)          pos(2)+pos(4)
    pos(1)+pos(3)/2 pos(2)+pos(4)
    pos(1)+pos(3)   pos(2)+pos(4)
    pos(1)+pos(3)   pos(2)+pos(4)/2
    pos(1)+pos(3)   pos(2)
    pos(1)+pos(3)/2 pos(2)
    pos(1)          pos(2)
    pos(1)          pos(2)+pos(4)/2];

% How bottom left relates to each anchor point

shift = [...
    0       -h
    -w/2    -h
    -w      -h
    -w      -h/2
    -w      0
    -w/2    0
    0       0
    0       -h/2];

% Legend location

corner = refxy(anchor(1),:) + buffer + shift(anchor(2),:);
legpos = [corner w h];

%------------------------
% Listener functions
%------------------------

% If user manually resizes the legend, update the app data

function updatelegappdata(src, evt, legax)
if ishandle(legax)
    Lf = getappdata(legax, 'legflex');
    pos = getpos(legax, 'px');
    Lf.w = pos(3);
    Lf.h = pos(4);
    setappdata(legax, 'legflex', Lf);
end
% If reference object moves or resizes, reposition the legend appropriately

function updatelegpos(src, evt, legax)
if ishandle(legax)
    Lf = getappdata(legax, 'legflex');
    legpos = positionleg(Lf.ref, Lf.w, Lf.h, Lf.anchor, Lf.buffer, Lf.bufunit);
    set(legax, 'Units', Lf.bufferunit, 'Position', legpos);
end

% Since figure resize can change axis size without actually triggering a
% listener, force this

function updatelegfigresize(src, evt)

allax = findall(src, 'type', 'axes');
for ii = 1:length(allax)
    isleg = ~isempty(getappdata(allax(ii), 'legflex'));
    if ~isleg
        pos = get(allax(ii), 'Position');
        set(allax(ii), 'Position', pos); % No change, just trigger PostSet
    end
end

% If plotted object changes, resync with legend

function resyncprops(src, evt, legax)

if ishandle(legax) % In case it's been deleted

    Lf = getappdata(legax, 'legflex');

    str = cellstr(num2str((1:length(Lf.plotobj))'));
    [htmp.leg, htmp.obj, htmp.labeledobj, htmp.textstr] = legend(Lf.plotobj, str);

    objtype = get(Lf.legobj, 'type');
    isline = strcmp(objtype, 'line');
    ispatch = strcmp(objtype, 'patch');
    ishg = strcmp(objtype, 'hggroup');
    hgidx = find(ishg);

    lobj = [Lf.legobj(isline) htmp.obj(isline)];
    pobj = [Lf.legobj(ispatch) htmp.obj(ispatch)];

    if ~isempty(hgidx)
        for ih = hgidx
            chldln1 = findall(Lf.legobj(ih), 'type', 'line');
            chldln2 = findall(htmp.obj(ih), 'type', 'line');

            lobj = [lobj; [chldln1 chldln2]];

            chldpa1 = findall(Lf.legobj(ih), 'type', 'patch');
            chldpa2 = findall(htmp.obj(ih), 'type', 'patch');

            pobj = [pobj; [chldpa1 chldpa2]];

        end
    end

    lprops = {'color','linestyle','linewidth','marker','markersize','markeredgecolor','markerfacecolor'};
    for il = 1:size(lobj,1)
        lvals = get(lobj(il,2), lprops);
        pv = [lprops; lvals];
        set(lobj(il,1), pv{:});
    end

    pprops = {'cdata','cdatamapping','edgealpha','edgecolor','facealpha','facecolor','linestyle','linewidth','marker','markeredgecolor','markerfacecolor','markersize'};
    for ip = 1:size(pobj,1)
        pvals = get(pobj(ip,2), pprops);
        pv = [pprops; pvals];
        set(pobj(ip,1), pv{:});
    end

    cmap = colormap(htmp.leg);
    colormap(legax, cmap);

    delete(htmp.leg);
end

% Wrapper to add multiple callback functions to resize

function wrapper(ObjH, EventData, fcnList)
for ii = 1:length(fcnList)
    feval(fcnList{ii}, ObjH, EventData);
end


function ft_sourcewrite(cfg, source)

% FT_SOURCEWRITE exports source-reconstructed results to gifti or nifti format file.
% The appropriate output file depends on whether the source locations are described by
% on a cortically constrained sheet (gifti) or by a regular 3D lattice (nifti).
%
% Use as
%  ft_sourcewrite(cfg, source)
% where source is a source structure obtained from FT_SOURCEANALYSIS and
% cfg is a structure that should contain
%
%   cfg.filename  = string, filename without the extension
%   cfg.filetype  = string, can be 'nifti', 'gifti' or 'cifti' (default is automatic)
%   cfg.parameter = string, functional parameter to be written to file
%   cfg.precision = string, can be 'single', 'double', etc.
%
% To facilitate data-handling and distributed computing you can use
%   cfg.inputfile   =  ...
% If you specify this the input data will be read from a *.mat
% file on disk. This mat file should contain only a single variable,
% corresponding with the input data structure.
%
% See also FT_SOURCEANALYSIS, FT_SOURCEDESCRIPTIVES, FT_VOLUMEWRITE

% Copyright (C) 2011, Jan-Mathijs Schoffelen
% Copyright (C) 2011-2014, Jan-Mathijs Schoffelen, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble debug
ft_preamble loadvar source
ft_preamble provenance source

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  return
end

% ensure that the required options are present
cfg = ft_checkconfig(cfg, 'required', {'parameter', 'filename'});

% get the options
cfg.parameter      = ft_getopt(cfg, 'parameter');
cfg.filename       = ft_getopt(cfg, 'filename');
cfg.filetype       = ft_getopt(cfg, 'filetype');        % the default is determined further down
cfg.brainstructure = ft_getopt(cfg, 'brainstructure');  % is used for cifti
cfg.parcellation   = ft_getopt(cfg, 'parcellation');    % is used for cifti
cfg.precision      = ft_getopt(cfg, 'precision');       % is used for cifti

% check if the input data is valid for this function
if strcmp(cfg.filetype, 'cifti')

  % keep the transformation matrix
  if isfield(source, 'transform')
    transform = source.transform;
  elseif isfield(source, 'brainordinate') && isfield(source.brainordinate, 'transform')
    transform = source.brainordinate.transform;
  else
    transform = [];
  end

  if isfield(source, 'brainordinate')
    % it is a parcellated source representation, i.e. the main structure one channel for each parcel
    brainordinate = source.brainordinate;
    source = rmfield(source, 'brainordinate');

    % split them and check individually
    source        = ft_checkdata(source, 'datatype', {'timelock', 'freq', 'chan'}, 'feedback', 'yes');
    brainordinate = ft_checkdata(brainordinate, 'datatype', 'parcellation', 'parcellationstyle', 'indexed', 'hasunit', 'yes');

    % merge them again
    source = copyfields(brainordinate, source, setdiff(fieldnames(brainordinate), {'cfg'}));
  else
    source = ft_checkdata(source, 'datatype', 'source', 'hasunit', true, 'feedback', 'yes');
  end

  % keep the transformation matrix
  if ~isempty(transform)
    source.transform = transform;
  end

end % if cifti

if isempty(cfg.filetype)
  if isfield(source, 'dim')
    % source positions are on a regular 3D lattice, save as nifti
    cfg.filetype = 'nifti';
  elseif isfield(source, 'tri')
    % there is a specification of a 2D cortical sheet, save as gifti
    cfg.filetype = 'gifti';
  else
    ft_error('the input data does not look like a 2D sheet, nor as a 3D regular volume');
  end
end

switch (cfg.filetype)
  case 'nifti'
    if numel(cfg.filename)<=4 || ~strcmp(cfg.filename(end-3:end), '.nii');
      cfg.filename = cat(2, cfg.filename, '.nii');
    end

    % convert functional data into 4D
    dat = getsubfield(source, cfg.parameter);
    dat = reshape(dat, source.dim(1), source.dim(2), source.dim(3), []);

    if ~isfield(source, 'transform')
      source.transform = pos2transform(source.pos);
    end

    % this is a bit of a kludge, but ft_write_mri can write 3D and 4D nifti
    ft_write_mri(cfg.filename, dat, 'dataformat', 'nifti', 'transform', source.transform);

  case 'gifti'
    if numel(cfg.filename)<=4 || ~strcmp(cfg.filename(end-3:end), '.gii');
      cfg.filename = cat(2, cfg.filename, '.gii');
    end

    % this is a bit of a kludge, but ft_write_headshape can write gifti including data
    ft_write_headshape(cfg.filename, source, 'data', getsubfield(source, cfg.parameter), 'format', 'gifti');

  case 'cifti'
    % brainstructure should represent the global anatomical structure, such as CortexLeft, Thalamus, etc.
    % parcellation should represent the detailled parcellation, such as BA1, BA2, BA3, etc.
    ft_write_cifti(cfg.filename, source, 'parameter', cfg.parameter, 'brainstructure', cfg.brainstructure, 'parcellation', cfg.parcellation, 'precision', cfg.precision);

  otherwise
    ft_error('unsupported output format "%s"', cfg.filetype);
end % switch filetype

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble previous source
ft_postamble provenance


% OtStart Start using the Omnitrans interface.
%
% Usage:
%    OtStart
%
% When finished, release the Omnitrans resources with a call to OtStop().
%
% To be able to use this interface, ensure the Omnitrans directory
% (with OtInterface.dll and all those BPL files) are on the system path.
% Otherwise, OtStart will fail.

% OtMatlab: Matlab interface to the Omnitrans transport planning software

% Copyright (c) 2008, VORtech Computing
% Copyright (c) 2010, Omnitrans International

% All rights reserved.

% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:

%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the distribution
%     * Neither the name of VORtech Computing and Omnitrans International nor the names
%       of its contributors may be used to endorse or promote products derived
%       from this software without specific prior written permission.

% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.

% 2006-02-28 Created (Johan Meijdam, VORtech)

function OtStart()
   Ot('start');
end


function showPrepDefaults(EEG, FID)
% Displays information about the defaults used for PREP pipeline steps
%
% Parameters:
%     EEG         a structure compatible with EEGLAB EEG structure
%     FID         (optional) an open file descriptor indication which
%                 file to output to. By default, this is the console
%                 or command window

%%
types = {'boundary', 'resample', 'globaltrend', 'detrend', ...
                'linenoise', 'reference', 'report', 'postprocess'};
if nargin < 1 || ~isstruct(EEG)
    error('showPrepDefaults:NotEnoughArguments', ...
         'first argument must be a structure');
elseif nargin < 2 || ~exist('FID', 'var')
    FID = 1;
end

indent = '  ';
for k = 1:length(types)
    theseDefaults = getPrepDefaults(EEG, types{k});
    theseFields = fieldnames(theseDefaults);
    fprintf(FID, '\nDefaults for %s:\n', types{k});
    for j = 1:length(theseFields)
        printNext(theseFields{j}, theseDefaults.(theseFields{j}));
    end
end

    function printNext(theField, theStruct)
       fprintf(FID, '%s%s:\n', indent, theField);
       fprintf(FID, '%s%svalue: %s\n', indent, indent, ...
           getString(theStruct.value));
       fprintf(FID, '%s%sclasses: %s\n', indent, indent, ...
           getString(theStruct.classes));
       fprintf(FID, '%s%sattributes: %s\n', indent, indent, ...
           getString(theStruct.attributes));
       fprintf(FID, '%s%sdescription:\n', indent, indent);
       printLines(FID, theStruct.description, 80, [indent indent indent]);
    end
end


function bbci_trigger_print(value)
%BBCI_TRIGGER_PRINT - Proxi for trigger function, just printing

v= clock;
time_str= sprintf('%02d:%02d:%06.3f', v(4), v(5), v(6));
fprintf('[TRIGGER PRINT] trig #%03d at %s\n', value, time_str);


function so = streamCdr(si)
% STREAMCDR  Returns the tail of a stream
so = forceEval(si{2});


function outcome=getOutcomeStr(obj, verbosity)
% give string indicating the outcome of the test
%
% outcome=getOutcomeStr(obj, verbosity)
%
% Inputs:
%   obj                 MOxUnitTestOutcome object
%   verbosity           Integer in the range [0,1,2]
%
% Returns:
%   outcome:            Depending on the value of verbosity
%                       0: ''
%                       1: '.'
%                       2: 'passed'
%

    outcome_cell={'','.','passed'};
    outcome=outcome_cell{verbosity+1};