function varargout = ChipDesign(varargin)
% LAYOUTGENERATOR Brief description of GUI.
%       Comments displayed at the command line in response 
%       to the help command. 

% (Leave a blank line following the help.)

%% Define Variables

guiFig = [];
chipFig = [];


chipCanvas = []; % axes to hold graphics
chipLayout = []; % uint matrix representation of chip

popup_ChipSpec = [];
popup_Pattern = [];
txtEdit_ProjectTitle = [];
txtEdit_Linker = [];
txtEdit_ContainerName = [];
txtEdit_ExposureTime = [];
txtEdit_Sequence = [];
txtLabel_Dimension = [];
txtLabel_SynthSpc = [];
txtLabel_NumFeat = [];
checkBox_SeqIn5to3 = [];
checkBox_Optimize = [];
checkBox_Randomize = [];
checkBox_FillChip = [];
pushbutton_SeqFile = [];
pushbutton_GenerateMask = [];
pushbutton_LoadTemplate = [];
pushbutton_SaveTemplate = [];

curState = struct;
curState.selChipSpecInd = 1;
curState.synthSpc = -1;
p = mfilename('fullpath'); c = mfilename; curState.programDir = p(1:end-length(c));
addpath(curState.programDir);
curState.templateDir = strcat(curState.programDir,'Templates');
addpath(curState.templateDir);
curState.designDir = strcat(curState.programDir,'Designs');
curState.lastDirOpened = curState.programDir;
curState.numFeat = 0;
curState.designLoaded = false;


chipOptions = struct;
chipSpec = struct;
pattern = struct;

%% Define Constants

% Color map: m by 3 matrix, each row is a color in rgb format
myColorMap = [0.15,0.15,0.15; ...
              1,1,1; ...
              1,1,0;];

BG_COLOR = [1,1,1]; % white
TXTEDIT_HEIGHT = 24;
TXTEDIT_WIDTH = 120;
TXTLABEL_HEIGHT = 18;
TXTLABEL_WIDTH = 90;
BTN_WIDTH = 80;
BTN_HEIGHT = 18;

%%  Initialization Tasks
createGuiFig();
createChipFig(); % default: hide chip layout preview on start up

disableGUI(); % disabling everything except for load button

%% Load/Save Template Functions
    function loadTemplate(source, eventdata)
        % open file dialog
        cd(curState.templateDir);
        [fileName,pathName, filterIndex] = uigetfile({'*.m';'*.mat'},'Select the Template File');

        try
            switch filterIndex
                case 1
                    % run .m script
                    cd(pathName);
                    fname = strcat(fileName(1:end-2), '()');
                    [chipOptions, chipSpec] = eval(fname);
                    cd(curState.programDir);
                case 2
                    % load .mat
                    temp = open(strcat(pathName,fileName));
                    chipOptions = temp.chipOptions;
                    chipSpec = temp.chipSpec;
                    pattern = temp.pattern;
                otherwise
                    % nothing, terminate loadTemplate function
                    return
            end

            % initialize figures based on data
            curState.designLoaded = true; % must be executed first
            enableGUI();
            resetChipFigPosition();
            setupPatternStruct();
            setup_popup_ChipSpec_menuItems();
            setup_popup_Pattern_menuItems();
            curState.selChipSpecInd = 1; % reset container selection to 1
            refreshGUI();
        catch ME1
            curState.designLoaded = false;
            disableGUI();
            
            % display error message
            errorMsg = {'Cannot open file due to:', ME1.message};
            errordlg(errorMsg);
            throw(ME1);
        end
    end

    function saveTemplate(source, eventdata)
        % open save file dialog, save in .mat format
        % will save: chipSpec, chipOptions, pattern
        cd(curState.designDir);
        outfile = strcat('Template_',chipOptions.projectTitle);
        uisave({'chipOptions','chipSpec','pattern'},outfile);
    end

    function setupPatternStruct()
        pattern = getDefaultPattern(); % get the standard set
        
        p = length(pattern);
        
        % add (probably redundant) pattern from chipSpec to pattern struct
        for i=1:length(chipSpec)
            % add to end of pattern struct
            p = p+1;
            pattern(p).name = strcat(chipSpec(i).name,' default');
            pattern(p).binMat = chipSpec(i).pattern;
            
            % set chipSpec(i) selPtnInd to p, this is for the pattern pop
            % up menu
            chipSpec(i).selPtnInd = p;
        end
    end
%% Construct GUI components
    function createGuiFig()
        guiFig = figure();
        
        FIG_WIDTH = 280;
        FIG_HEIGHT = 550;
        
        set(guiFig, 'Position', [0,0,FIG_WIDTH,FIG_HEIGHT], ...
                    'CloseRequestFcn', @closeProgram, ...
                    'MenuBar', 'none', ...
                    'NumberTitle', 'off', ...
                    'Color', BG_COLOR, ...
                    'Name', 'Property Panel', ...
                    'Resize', 'off', ...
                    'Visible', 'off');
        
        movegui(guiFig, 'east'); 
        set(guiFig, 'Visible', 'on');
        
        createChipOptionsPanel();
        createChipSpecPanel();
        createButtons();
    end

    function createChipOptionsPanel()        
        % Setup Panel
        panel_ChipOpt = uipanel(guiFig, 'Units', 'pixels', ...
                        'Position', [10,390,260,150], ...
                        'Title', 'Chip Options', ...
                        'TitlePosition', 'centertop', ...
                        'BackgroundColor', BG_COLOR);
                    
        % Setup Field Header
        uicontrol(panel_ChipOpt,'Style','text',...
                'Position',[10, 105, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Project Title', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipOpt,'Style','text',...
                'Position',[10, 75, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Linker Sequence', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipOpt,'Style','text',...
                'Position',[10, 45, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Dimension', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipOpt,'Style','text',...
                'Position',[10, 15, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Synthesis Space', ...
                'BackgroundColor', BG_COLOR);

        % Setup Data Field
        txtEdit_ProjectTitle = uicontrol(panel_ChipOpt,'Style','edit',...
                'Position',[120, 105, TXTEDIT_WIDTH, TXTEDIT_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @txtEdit_ProjectTitle_Callback);
        txtEdit_Linker = uicontrol(panel_ChipOpt,'Style','edit',...
                'Position',[120, 75, TXTEDIT_WIDTH, TXTEDIT_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @txtEdit_Linker_Callback);
        txtLabel_Dimension = uicontrol(panel_ChipOpt,'Style','text',...
                'Position',[120, 45, TXTEDIT_WIDTH, TXTLABEL_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR);
        txtLabel_SynthSpc = uicontrol(panel_ChipOpt,'Style','text',...
                'Position',[120, 15, TXTEDIT_WIDTH, TXTLABEL_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR);
    end

    function createChipSpecPanel()

        % Setup Panel
        panel_ChipSpec = uipanel(guiFig, 'Units', 'pixels', ...
                        'Position', [10,40,260,340], ...
                        'Title', 'Chip Specification', ...
                        'TitlePosition', 'centertop', ...
                        'BackgroundColor', BG_COLOR);
                 
        % Setup Field Headers
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 290, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Select Container', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 260, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Name', ...
                'BackgroundColor', BG_COLOR);         
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 230, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Pattern', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 200, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', '# of features', ...
                'BackgroundColor', BG_COLOR);  
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 170, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Sequence', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 140, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', '5'' -> 3''', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 110, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Exposure Time', ...
                'BackgroundColor', BG_COLOR);            
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 80, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Optimize', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 50, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Randomize', ...
                'BackgroundColor', BG_COLOR);
        uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[10, 20, TXTLABEL_WIDTH, TXTLABEL_HEIGHT], ...
                'String', 'Fill Container', ...
                'BackgroundColor', BG_COLOR);
        
        % Setup TextLabel
        txtLabel_NumFeat = uicontrol(panel_ChipSpec,'Style','text',...
                'Position',[120, 200, TXTEDIT_WIDTH, TXTLABEL_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR);
            
        % Setup Text Edit Data Fields
        txtEdit_ContainerName = uicontrol(panel_ChipSpec,'Style','edit',...
                'Position',[120, 260, TXTEDIT_WIDTH, TXTEDIT_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @txtEdit_ContainerName_Callback);
        txtEdit_Sequence = uicontrol(panel_ChipSpec,'Style','edit',...
                'Position',[120, 170, TXTEDIT_WIDTH - 25, TXTEDIT_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @txtEdit_Sequence_Callback);
        txtEdit_ExposureTime = uicontrol(panel_ChipSpec,'Style','edit',...
                'Position',[120, 110, TXTEDIT_WIDTH, TXTEDIT_HEIGHT], ...
                'String', '', ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @txtEdit_ExposureTime_Callback);
        
        % Setup Buttons
        pushbutton_SeqFile = uicontrol(panel_ChipSpec,'Style','pushbutton',...
                'Position',[120+TXTEDIT_WIDTH-25, 170+2, 20, 20], ...
                'String', '...', ...
                'Callback', @pushbutton_SeqFile_Callback);
            
        % Setup Popup Menu
        popup_ChipSpec = uicontrol(panel_ChipSpec,'Style','popupmenu',...
                'Position',[120, 290, TXTEDIT_WIDTH, TXTEDIT_HEIGHT],...
                'Callback',@chipSpecPopupMenu_Callback);
        setup_popup_ChipSpec_menuItems();
        
        popup_Pattern = uicontrol(panel_ChipSpec,'Style','popupmenu',...
                'Position',[120, 230, TXTEDIT_WIDTH, TXTEDIT_HEIGHT], ...
                'Callback', @patternPopupMenu_Callback);
        setup_popup_Pattern_menuItems();
        
        % Setup Checkboxes
        checkBox_SeqIn5to3 = uicontrol(panel_ChipSpec,'Style','checkbox',...
                'Position',[120+50, 140, TXTEDIT_HEIGHT, TXTEDIT_HEIGHT], ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @checkBox_SeqIn5to3_Callback);
        checkBox_Optimize = uicontrol(panel_ChipSpec,'Style','checkbox',...
                'Position',[120+50, 80, TXTEDIT_HEIGHT, TXTEDIT_HEIGHT], ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @checkBox_Optimize_Callback);
        checkBox_Randomize = uicontrol(panel_ChipSpec,'Style','checkbox',...
                'Position',[120+50, 50, TXTEDIT_HEIGHT, TXTEDIT_HEIGHT], ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @checkBox_Randomize_Callback);
        checkBox_FillChip = uicontrol(panel_ChipSpec,'Style','checkbox',...
                'Position',[120+50, 20, TXTEDIT_HEIGHT, TXTEDIT_HEIGHT], ...
                'BackgroundColor', BG_COLOR, ...
                'Callback', @checkBox_FillChip_Callback);
        
    end

    function createButtons()
        pushbutton_LoadTemplate = uicontrol(guiFig,'Style','pushbutton',...
                'Position',[15, 10, BTN_WIDTH, BTN_HEIGHT], ...
                'String', 'Load', ...
                'Callback', @loadTemplate);
        pushbutton_SaveTemplate = uicontrol(guiFig,'Style','pushbutton',...
                'Position',[20, 10, BTN_WIDTH, BTN_HEIGHT], ...
                'String', 'Save', ...
                'Callback', @saveTemplate);
        pushbutton_GenerateMask = uicontrol(guiFig,'Style','pushbutton',...
                'Position',[30, 10, BTN_WIDTH, BTN_HEIGHT], ...
                'String', 'Generate', ...
                'Callback', @pushbutton_GenerateMask_Callback);
        btnList = [pushbutton_LoadTemplate, pushbutton_SaveTemplate, pushbutton_GenerateMask];
        align(btnList, 'Fixed', 5, 'Bottom');
    end

    function setup_popup_ChipSpec_menuItems()
        if (isempty(fieldnames(chipSpec)))
            set(popup_ChipSpec, 'String', ' ');
        else
            menuItems = {};
            for i=1:length(chipSpec)
                menuItems{i} = chipSpec(i).name;
            end
            set(popup_ChipSpec, 'String', menuItems);
        end
    end

    function setup_popup_Pattern_menuItems()  
        if (isempty(fieldnames(pattern)))
            set(popup_Pattern, 'String', ' ');
        else
            menuItems = {};
            for i=1:length(pattern)
                menuItems{i} = pattern(i).name;
            end
            set(popup_Pattern, 'String', menuItems);
        end
    end

%% Callbacks Property Panel
    function chipSpecPopupMenu_Callback(source, eventdata)
        curState.selChipSpecInd = get(source,'Value');
        refreshGUI();
    end

    function patternPopupMenu_Callback(source, eventdata)
        ptnInd = get(source,'Value');
        
        % check if pattern can fit within chipSpec container
        ptnFit = true; % assume pattern fits, check for violations below
        
        % find biggest rectangle dimension in pattern
        subPtn = parsePattern(pattern(ptnInd).binMat);
        subPtnH = subPtn(:,3)-subPtn(:,1)+1;
        subPtnW = subPtn(:,4)-subPtn(:,2)+1;
        ptnH = max(subPtnH); ptnW = max(subPtnW);
        
        % find smallest rectangle dimension in pattern
        boundary = chipSpec(curState.selChipSpecInd).boundary;
        containerH = min(boundary(:,3)-boundary(:,1)+1); % r2-r1+1
        containerW = min(boundary(:,4)-boundary(:,2)+1); % c2-c1+1

        % compare width and height
        % if pattern is bigger than any of the rect region in container,
        % it's invalid
        if (ptnH > containerH|| ptnW > containerW)
            ptnFit = false;
        end

        if (ptnFit)
            chipSpec(curState.selChipSpecInd).pattern = pattern(ptnInd).binMat;
            chipSpec(curState.selChipSpecInd).selPtnInd   = ptnInd; 
        else
            % reset pattern popup menu to previously selected entry
           set(source,'Value',chipSpec(curState.selChipSpecInd).selPtnInd);
        end
        refreshGUI();
    end

    function txtEdit_ProjectTitle_Callback(source, eventdata)
        chipOptions.projectTitle = get(source, 'String');
    end

    function txtEdit_Linker_Callback(source, eventdata)
        chipOptions.linkerSeq = get(source, 'String');
    end

    function txtEdit_ContainerName_Callback(source, eventdata)
        chipSpec(curState.selChipSpecInd).name = get(source, 'String');
        setup_popup_ChipSpec_menuItems(); % regenerate container popup list
    end

    function txtEdit_ExposureTime_Callback(source, eventdata)
        expTime = sscanf(  get(source, 'String'), '%g' ); % convert string to int
        chipSpec(curState.selChipSpecInd).exposureTime = expTime;
    end

    function txtEdit_Sequence_Callback(source, eventdata)
        s = regexprep(get(source, 'String'), '\s', '');
        set(source,'String',s);
        chipSpec(curState.selChipSpecInd).seqFile = s;
    end

    function checkBox_SeqIn5to3_Callback(source, eventdata)
        chipSpec(curState.selChipSpecInd).seqIn5to3dir = logical( get(source,'Value') );
    end

    function checkBox_Optimize_Callback(source, eventdata)
        chipSpec(curState.selChipSpecInd).optimize = logical( get(source,'Value') );
    end

    function checkBox_Randomize_Callback(source, eventdata)
        chipSpec(curState.selChipSpecInd).randomize = logical( get(source,'Value') );
    end

    function checkBox_FillChip_Callback(source, eventdata)
        chipSpec(curState.selChipSpecInd).fillArea = logical( get(source,'Value') );
    end

    function pushbutton_SeqFile_Callback(source, eventdata)
        cd(curState.lastDirOpened);
        [FileName,PathName] = uigetfile({'*.txt';'*.csv';'*.*'},'Select the Sequence File');
        
        if (FileName ~= 0)
            chipSpec(curState.selChipSpecInd).seqFile = strcat(PathName, FileName);
            updateChipSpecPanel(); %refresh panel
            
            curState.lastDirOpened = PathName;
        end
    end

    function pushbutton_GenerateMask_Callback(source, eventdata)
        % run MaskGenerator
        MaskGenerator(chipSpec, chipOptions);
        
        % Mask Generator will remove path... need to readd it
        addpath(curState.programDir);
    end

    function updateChipSpecPanel()
        % read currently selected chip specification and display data to chip spec panel
        set(popup_ChipSpec, 'Value', curState.selChipSpecInd);
        set(popup_Pattern, 'Value', chipSpec(curState.selChipSpecInd).selPtnInd);
        set(txtEdit_ContainerName, 'String', chipSpec(curState.selChipSpecInd).name);
        set(txtEdit_Sequence, 'String', chipSpec(curState.selChipSpecInd).seqFile);
        set(txtEdit_ExposureTime, 'String', chipSpec(curState.selChipSpecInd).exposureTime);
        set(checkBox_SeqIn5to3, 'Value', chipSpec(curState.selChipSpecInd).seqIn5to3dir);
        set(checkBox_Optimize, 'Value', chipSpec(curState.selChipSpecInd).optimize);
        set(checkBox_Randomize, 'Value', chipSpec(curState.selChipSpecInd).randomize);
        set(checkBox_FillChip, 'Value', chipSpec(curState.selChipSpecInd).fillArea);
        set(txtLabel_NumFeat, 'String', curState.numFeat);
    end

    function updateChipOptionsPanel()
        % read chip options and display data to panel
        set(txtEdit_ProjectTitle, 'String', chipOptions.projectTitle);
        set(txtEdit_Linker, 'String', chipOptions.linkerSeq);
        set(txtLabel_Dimension, 'String', strcat(int2str(chipOptions.width), 'x', int2str(chipOptions.height)));
        set(txtLabel_SynthSpc, 'String', curState.synthSpc);
    end

%%  Callbacks for Chip Figure
    function createChipFig()
        chipFig = figure('MenuBar', 'none', 'Name', 'Chip Layout Preview', ...
                'NumberTitle', 'off');
            
        set(chipFig, 'ToolBar','figure', ...
                        'Resize','on', ...
                        'CloseRequestFcn', @closeProgram, ...
                        'Visible', 'off');

        if (isempty(fieldnames(chipOptions)))
            set(chipFig, 'Position', [0,0,800,600]); % arbitrary size
        else
            set(chipFig, 'Position', [0,0,chipOptions.width,chipOptions.height]);
        end
                    
        movegui(chipFig,'northwest');
    end

    function updateChipFig()
        genChipImg();
        
        % 2 rendering modes
        % pcolor is too slow so bitmap is used as default
        %renderChipPColor();
        renderChipBitmap();
    end

    function renderChipPColor()
        chipCanvas = axes('Units','normalized','Position',[0,0,1,1]);
        set(chipCanvas, 'Parent',chipFig);
        
        colormap(myColorMap);

        chipLayout(end+1,end+1) = 0; % expand border by 1pixel for pcolor to render properly
        
        pcolor(chipCanvas, double(chipLayout) );
        axis(chipCanvas,'ij','equal','tight');
        
    end

    function renderChipBitmap()   
        figure(chipFig); % switch focus for chip figure

        % clear figure?
        delete(chipCanvas);
        
        % code to switch between 100% zoom and fill figure window
        temp = get(chipFig, 'Position');
        fWidth = temp(3); fHeight = temp(4);
        
        if (fWidth <= chipOptions.width || fHeight <= chipOptions.height)
            leftOffset = floor((fWidth - chipOptions.width)/2);
            bottomOffset = floor((fHeight - chipOptions.height)/2);
            chipCanvas = axes('Units','pixel','Position',[leftOffset,bottomOffset,chipOptions.width,chipOptions.height]);
        else
            chipCanvas = axes('Units','normalized','Position',[0,0,1,1]);
        end
        
        % display image
        image(chipLayout);        
        colormap(myColorMap);
        
        axis off;
        axis image;
    end

    function genChipImg()
        h = waitbar(0, 'Generating chip preview...','Visible','off');
        movegui(h,'center'); set(h,'Visible','on');
        
        curState.synthSpc = 0;
        chipLayout = uint8( zeros(chipOptions.height,chipOptions.width) );
        for i=1:length(chipSpec)
            coord = [];
            boundMat = chipSpec(i).boundary;
            for j=1:size(boundMat,1)
                coord = [coord; genCoordMat(boundMat(j,:), chipSpec(i).pattern)];
            end
            
            temp = uint8( mapBlocks2Mask(chipOptions.height, chipOptions.width, coord) );
            
            if (isempty(chipSpec(i).PROBE_CLASS)) % if it's not a control sequence
                curState.synthSpc = curState.synthSpc + size(coord,1);
            end
            
            if (i == curState.selChipSpecInd)
                curState.numFeat = size(coord,1);
                chipLayout = chipLayout + 2.*temp;
            else
                chipLayout = chipLayout + temp;
            end
            
            waitbar(i/length(chipSpec)); % update waitbar
        end
        
        close(h);
    end

    function resetChipFigPosition()
        set(chipFig, 'Position', [0,0,chipOptions.width,chipOptions.height]);
        movegui(chipFig, 'northwest');
    end

%% Callbacks for the program
    function calcSynthSpc()
        % extremely inefficient and redundant, but it works for now...
        curState.synthSpc = 0;
        for i=1:length(chipSpec)
            if (isempty(chipSpec(i).PROBE_CLASS)) % if it's not a control sequence
                boundMat = chipSpec(i).boundary;
                for j=1:size(boundMat,1)
                    temp = size( genCoordMat(boundMat(j,:), chipSpec(i).pattern), 1);
                    curState.synthSpc = curState.synthSpc + temp;
                end
            end
        end
    end

    function refreshGUI()
        %calcSynthSpc();
        
        if (curState.designLoaded)
            % order of execution is important, synthspc is calculated in
            % updateChipFig()
            updateChipFig();
            updateChipOptionsPanel();
            updateChipSpecPanel();
        end
    end

    function disableGUI()
        % disable ...
        set(pushbutton_SeqFile,'Enable','off');
        set(popup_ChipSpec,'Enable','off');
        set(popup_Pattern,'Enable','off');
        set(pushbutton_GenerateMask,'Enable','off');
        set(pushbutton_SaveTemplate,'Enable','off');
    end

    function enableGUI()
        if (curState.designLoaded)
            set(chipFig, 'Visible', 'on');
            set(pushbutton_SeqFile,'Enable','on');
            set(popup_ChipSpec,'Enable','on');
            set(popup_Pattern,'Enable','on');
            set(pushbutton_GenerateMask,'Enable','on');
            set(pushbutton_SaveTemplate,'Enable','on');
        end
    end

    function closeProgram(source, eventdata)
        delete(chipFig);
        delete(guiFig);
        rmpath(curState.programDir);
        rmpath(curState.templateDir);
    end
end