function dlgstruct = getDialogSchema(this, name)
%

%   Copyright 2012-2016 The MathWorks, Inc.

switch (name)
    case 'MessageBox'
        dlgstruct = i_message_box(this,'msgbox');
    case 'InputDialog'
        dlgstruct = i_input_dialog(this);
    case 'ErrorDialog'
        dlgstruct = i_message_box(this,'errordlg');
    case 'WarnDialog'
        dlgstruct = i_message_box(this,'warndlg');
    case 'QuestionDialog'
        dlgstruct = i_question_dialog(this);
    case 'ListDialog'
        dlgstruct = i_list_dialog(this);
    otherwise
        assert(false,'DAStudio:DialogProvider:BadInput',...
            sprintf('Unexpected dialog schema name: %s',name));
end

if ~isempty(this.DisplayIcon)
    dlgstruct.DisplayIcon = this.DisplayIcon;
end

end

%----------------------------------------------------
function dlgstruct = i_input_dialog(this)

data = this.pDialogData;
dlgstruct.DialogTitle = data.Title;

prompt.Type = 'text';
prompt.Name = data.Prompt;
prompt.Tag = 'prompt';
prompt.ColSpan = [1 1];
prompt.RowSpan = [1 1];

if data.InputDlgMultiline
    input.Type = 'editarea';
else
    input.Type = 'edit';
end
input.Value = data.DefaultAnswer;
input.Tag = 'input';
input.ColSpan = [1 1];
input.RowSpan = [2 2];

dlgstruct.LayoutGrid = [2 1];
dlgstruct.StandaloneButtonSet = {'OK','Cancel'};
dlgstruct.Sticky = true; % modal
dlgstruct.DialogTag = 'inputdlg';
dlgstruct = i_dialog_callback(dlgstruct,'inputdlg');
dlgstruct.Source = this;
dlgstruct.Items = {prompt, input};

end

%----------------------------------------------------
function dlgstruct = i_message_box(this,type)

if strcmp(type,'msgbox')
    cols = 1;
    need_image = false;
else
    % warning or error
    cols = 2;
    need_image = true;
end


data = this.pDialogData;
dlgstruct.DialogTitle = data.Title;

message.Type = 'text';
message.Name = data.Message;
message.Alignment = 5; % centre left
message.Tag = 'message';
message.WordWrap = true; % too narrow if we do this.
message.ColSpan = [cols cols];
message.RowSpan = [1 1];

% Adjust the size of the text field depending on the length of the longest
% line of text in the message. The exact size doesn't matter - the message
% will wrap if it turns out to be too wide.

exp = '<p><ul\sstyle="padding-left:15px"><li(?:\sstyle="list-style-type:none")?>(\s*(.*)\s*)</li></ul></p>';
inner = regexp(message.Name, exp, 'tokens');

if isempty(inner)
    inner = message.Name;
else
    inner = char(inner{:});
end

m = max(cellfun('length',strsplit(inner,"<br/>")));
n = max(cellfun('length',strsplit(inner, newline)));
o = min(m, n);
width = o*7+10;
width = min(width,800);
width = max(width,200);
message.MinimumSize = [width, 50];

if need_image
    image.Type = 'image';
    image.Tag = 'image';
    image.Alignment = 5; % centre left
    image.RowSpan = [1 1];
    image.ColSpan = [1 1];
    if ~isempty(this.DialogImage)
        image.FilePath = this.DialogImage;
    elseif strcmp(type,'errordlg')
        image.FilePath = fullfile(matlabroot,'toolbox','shared','dastudio','resources','error.png');
    else
        assert(strcmp(type,'warndlg'));
        image.FilePath = fullfile(matlabroot,'toolbox','shared','dastudio','resources','warning.png');
    end
end

% Create our own "OK" button so that we can centre it.
button.Type = 'pushbutton';
button.Name = 'OK';
button.Tag = 'OK';
button = i_control_callback(button,'MsgBox');

buttonGroup.Type = 'panel';
buttonGroup.LayoutGrid = [1 1];
buttonGroup.Items = {button};
buttonGroup.RowSpan = [2 2];
buttonGroup.ColSpan = [1 cols];
buttonGroup.Alignment = 6; % button uses its own size; centred in both directions

dlgstruct.LayoutGrid = [2 cols];
dlgstruct.StandaloneButtonSet = {''}; % no button bar
dlgstruct.Sticky = true; % modal
dlgstruct.DialogTag = type;

if need_image
    dlgstruct.ColStretch = [0 1];
    dlgstruct.RowStretch = [1 0];
    dlgstruct.Items = {image, message, buttonGroup};
else
    dlgstruct.Items = {message, buttonGroup};
end

end

%----------------------------------------------------
function dlgstruct = i_question_dialog(this)

data = this.pDialogData;
dlgstruct.DialogTitle = data.Title;

prompt.Type = 'text';
prompt.Name = data.Prompt;
prompt.Alignment = 5; % centre left
prompt.Tag = 'message';
prompt.ColSpan = [2 2];
prompt.RowSpan = [1 1];
prompt.WordWrap = true;
prompt.MinimumSize = [300, 50];

image.Type = 'image';
image.Tag = 'image';
image.RowSpan = [1 1];
image.ColSpan = [1 1];
if ~isempty(this.DialogImage)
    image.FilePath = this.DialogImage;
else    
    image.FilePath = fullfile(matlabroot,'toolbox','shared','dastudio','resources','question.png');
end

items = cell(1,numel(data.Buttons));
for i=1:numel(items)
    button.Type = 'pushbutton';
    button.Name = data.Buttons{i};
    tag = ['QuestDlg_',data.Buttons{i}];
    button.Tag = tag;
    button = i_control_callback(button,tag);    
    button.RowSpan = [1 1];
	button.ColSpan = [i i];
    items{i} = button;
end

buttonGroup.Type = 'panel';
buttonGroup.LayoutGrid = [1 1];
buttonGroup.Items = items;
buttonGroup.RowSpan = [2 2];
buttonGroup.ColSpan = [1 2];
buttonGroup.Alignment = 6; % centred in both directions

dlgstruct.LayoutGrid = [2 2];
dlgstruct.StandaloneButtonSet = {''}; % no button bar
dlgstruct.Sticky = true; % modal
dlgstruct.RowStretch = [1 0];
dlgstruct.ColStretch = [0 1];
dlgstruct.DialogTag = 'questdlg';
dlgstruct.Items = {image, prompt, buttonGroup};

end

%----------------------------------------------------
function dlgstruct = i_list_dialog(this)

data = this.pDialogData;
hasinfo = ~isempty(data.ItemInfo);

prompt.Type = 'text';
prompt.Name = data.Prompt;
prompt.Alignment = 5; % centre left
prompt.Tag = 'message';
prompt.ColSpan = [1 1];
prompt.RowSpan = [1 1];

list.Type = 'listbox';
list.ColSpan = [1 1];
list.RowSpan = [2 2];
list.Tag = 'list';
list.ListDoubleClickCallback = @i_doubleclick;
list.MultiSelect = false;
list.Entries = data.ListString;
if hasinfo
    list = i_control_callback(list,'list');
end

info.Type = 'text';
info.Name = sprintf(' \n \n%s\n \n',... % leave some space
    DAStudio.message('modelexplorer:message:ClickForDescription'));
info.Tag = 'info';
info.WordWrap = true;
info.ColSpan = [1 1];
info.RowSpan = [3 3];

if hasinfo
    dlgstruct.LayoutGrid = [3 1];
    dlgstruct.Items = {prompt, list, info};
else
    dlgstruct.LayoutGrid = [2 1];
    dlgstruct.Items = {prompt, list};
end
dlgstruct.StandaloneButtonSet = {'OK','Cancel'};
dlgstruct.Sticky = true; % modal
dlgstruct.DialogTag = 'listdlg';
dlgstruct.DialogTitle = data.Title;
dlgstruct = i_dialog_callback(dlgstruct,'listdlg');

end

%--------------------------
function i_doubleclick(dlg,tag,index) %#ok<INUSD>
obj = dlg.getSource;
obj.pDialogCallback('listdlg',dlg);
delete(dlg);
end

%--------------------------
function item = i_control_callback(item,key)
item.ObjectMethod = 'pControlCallback';
item.MethodArgs = {key,'%dialog'};
item.ArgDataTypes = {'string','handle'};
end


%--------------------------
function s = i_dialog_callback(s,key)
s.PreApplyMethod = 'pDialogCallback';
s.PreApplyArgs = {key,'%dialog'};
s.PreApplyArgsDT = {'string','handle'};
end
