%--------------------------------------------------------------------------
function peripheralTabhandling(hObject, handles, action, userdata)
%PERIPHERALTABHANDLING Handle callback actions

% Copyright 2006-2009 The MathWorks, Inc.

if ~isfield(userdata, 'peripherals')
    return
else
    switch (userdata.chipInfo.subFamily)
    case '281x'
        periphCont = userdata.peripherals.c281x;
        periphPropCont = userdata.peripherals.properties.c281x;
    case {'280x','2804x'}
        periphCont = userdata.peripherals.c280x;
        periphPropCont = userdata.peripherals.properties.c280x;
    case '2833x'
        periphCont = userdata.peripherals.c2833x; 
        periphPropCont = userdata.peripherals.properties.c2833x;
    case '2802x'
        periphCont = userdata.peripherals.c2802x; 
        periphPropCont = userdata.peripherals.properties.c2802x;
    otherwise
        return
    end
end

switch action
    case 'listbox_periph_CreateFcn'
        periphName1 = fieldnames(periphCont);
        periphName = {};
        for i=1:length(periphName1)
            periphObj = eval(['periphCont.', periphName1{i}]);
            if ischar(periphObj)
                continue
            else
                periphName{length(periphName) + 1} = periphName1{i};
            end
        end
        set(hObject, 'String', periphName);
        parentHD = get(hObject, 'Parent');
        targetName = ['c',userdata.chipInfo.subFamily];
        addPropPanels(parentHD, handles, targetName, periphCont, periphPropCont);        
    case 'listbox_periph_DeleteFcn'
        % delete all peripheral panels (start with panel_)
        parentHD = get(hObject, 'Parent');
        deletePropPanels(parentHD, handles);        
    case 'listbox_periph_Callback'
        contents = get(hObject, 'String');
        selectedIdx = get(hObject, 'Value');
        for i = 1:length(contents)
            if ~isfield (handles, ['panel_' contents{i}]), continue; end
            if i == selectedIdx
                eval(['set(handles.panel_' contents{i} ', ''visible'', ''on'');']);
            else
                eval(['set(handles.panel_' contents{i} ', ''visible'', ''off'');']);
            end
        end
end


%--------------------------------------------------------------------------
function addPropPanels(parentHD, handles, targetName, periphCont, periphPropCont)
%% Add panels for all peripherals
periphName1 = fieldnames(periphCont);
periphName = {};
for i=1:length(periphName1)
    periphObj = eval(['periphCont.', periphName1{i}]);
    if ischar(periphObj)
        continue
    else
        periphName{length(periphName) + 1} = periphName1{i};
    end 
end 
sortedList = sort(periphName);
for i = 1:length(periphName)
    periphObj = eval(['periphCont.', periphName{i}]);
    if ischar(periphObj) continue; end
    if  strcmp(periphName{i}, sortedList{1})
        visible = 'on'; %% initially set first panel visible 
    else
        visible = 'off';
    end
    title = [periphName{i} ' properties'];
    tag = ['panel_' periphName{i}];
    panelHD = uipanel('Title', title, 'Parent', parentHD);
    set(panelHD, 'Tag', tag);
    set(panelHD, 'visible', visible);
    set(panelHD, 'Units', 'characters');
    set(panelHD, 'Position', [20 1 63 34]);
	set(panelHD, 'BorderType', 'etchedin');
    handles.(tag) = panelHD;
    addComponentToPanel(panelHD, handles, targetName, periphObj, periphName{i}, periphPropCont);    
end
guidata(parentHD, handles);


%--------------------------------------------------------------------------
function deletePropPanels(parentHD, handles)
% delete all peripheral panels (start with panel_)
fields = fieldnames(handles);
for i=1:length(fields)
    if strmatch('panel_', fields{i})
       delete (eval(['handles.' fields{i}])); 
       handles=rmfield(handles, fields{i});
    end    
end
guidata(parentHD, handles);


%--------------------------------------------------------------------------
function addComponentToPanel(panelHD, handles, targetName, periphObj, periphName, periphPropCont)
%% Add comp[onents of each peripheral to its panel
propName = fieldnames(periphObj);

j = 0;
x_lbl = 0.5;	y_lbl = 32.5;   % position of labels
w_lbl = 27;	    h_lbl = 1.7;    % width and height of label
x_prop = 25.5;	y_prop = y_lbl+0.3;  % position of widget
w_prop = 35.5;	h_prop = h_lbl; % width and height of the widget
dy = 1.9;                       % vertical distance between two lines
%
for i = 1: length(fieldnames(periphObj))

    %add text label
periphObjStr = fieldnames(periphObj);
periphObjValue = eval(['periphObj.',periphObjStr{i}]);
labelStr = eval(['periphPropCont.prompt.', periphName,'.', periphObjStr{i}]);
propDataType = eval(['periphPropCont.fields.',  periphName, '.', propName{i}]); % get initial value 
    if labelStr(end) ~= ':' && ~isequal(propDataType,'on/off')
        labelStr(end+1) = ':';
    end
    labelHD = uicontrol('Parent', panelHD, 'Style', 'text', 'String', labelStr);
    set(labelHD, 'Units', 'characters');
    set(labelHD, 'Position', [x_lbl, y_lbl-dy*(i+j), w_lbl, h_lbl]);
    set(labelHD, 'HorizontalAlignment', 'left');

    %add uicontrol component
    %-- setup ui style and initial value

    if ischar(propDataType)
        switch propDataType
        case 'on/off'
            hd = uicontrol('Parent', panelHD, 'Style', 'checkbox');
            registerCallbacks(hd, periphObj, periphName, propName{i});
                if strcmp(periphObjValue, 'on')
                set(hd, 'Value', 1)
            else
                set(hd, 'Value', 0)
            end
            case 'edit'
            hd = uicontrol('Parent', panelHD, 'Style', 'edit');
            registerCallbacks(hd, periphObj, periphName, propName{i});
			set(hd, 'BackgroundColor', 'white');
                set(hd, 'String', num2str(periphObjValue));                  
            case 'string'
                hd = uicontrol('Parent', panelHD, 'Style', 'edit');
                registerCallbacks(hd, periphObj, periphName, propName{i});                
	            set(hd, 'BackgroundColor', 'white');           
                set(hd, 'String', periphObjValue);              
            case 'pushbotton'
				hd = uicontrol('Parent', panelHD, 'Style', 'pushbutton');
				registerCallbacks(hd, periphObj, periphName, propName{i});
                set(hd, 'String', periphObjValue);                
        end
    else  %custom enum data type
            hd = uicontrol('Parent', panelHD, 'Style', 'popupmenu');
            registerCallbacks(hd, periphObj, periphName, propName{i});
        set(hd, 'String', propDataType);
        idx = find(strcmp(periphObjValue, propDataType));
            set(hd, 'Value', idx);
			set(hd, 'BackgroundColor', 'white');
    end


    set(hd, 'HorizontalAlignment', 'left');
    set(hd, 'Units', 'characters');
    set(hd, 'tag', ['uicontrol_', periphName, '_', propName{i}]);
    set(hd, 'Position', [x_prop, y_prop-dy*(i+j), w_prop, h_prop]);
    
end
%invoke UIInitFcn Callback (Initial Callback)
uiObjSet = get(panelHD, 'Children');
for i = 1:length(propName)
    if exist([periphName, propName{i},'_UIInitFcn'])~=0
        tagStr = ['uicontrol_', periphName, '_', propName{i}];
        uiObj = findall(uiObjSet, 'Tag', tagStr);
        peripheralCallbackDisp(uiObj, [], handles, periphName, propName{i}, 'UIInitFcn');
    end
end
%invoke UILayout Callback (Rearrange the layout of the panel)
if (exist([periphName,'_UILayout'])~=0)
    if ~strcmp(periphName,'DMA_ch1')
    eval([periphName '_UILayout(handles,panelHD,uiObjSet)']);
end
end
switch periphName
    case{'DMA_ch1','DMA_ch2','DMA_ch3','DMA_ch4','DMA_ch5','DMA_ch6'}
        eval(['DMA_ch1_UILayout(handles,panelHD,uiObjSet,periphName)']);
end


%--------------------------------------------------------------------------
function maxlength = maxcell(cellin)
maxlength = 0;
for i = 1:length(cellin)
    if maxlength < length(cellin{i})
        maxlength = length(cellin{i});
    end
end


%--------------------------------------------------------------------------
function registerCallbacks(hd, periphObj, periphName, propName)
CallbackFcn = 'peripheralCallbackDisp';
CallbackArg = ['(gcbo, [], guidata(gcbo),''' periphName, ''',''',propName ''','];
set(hd, 'Callback', [CallbackFcn CallbackArg '''UICallback'')']);
if ismethod(periphObj, [propName '_UIDeleteFcn']) %% to be called when you close the GUI
    set(hd, 'DeleteFcn', [CallbackFcn CallbackArg '''UIDelete'')']);
end
