function varargout = calculator(varargin)
% CALCULATOR MATLAB code for calculator.fig
% 简易计算器，支持含x的多项式符号计算与纯数字计算，支持角度制三角函数，支持分数/小数显示切换

% 初始化 GUI
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @calculator_OpeningFcn, ...
                   'gui_OutputFcn',  @calculator_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end

% --- 初始化函数
function calculator_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
global expression showFraction;
expression = '';
showFraction = true;

% --- 输出函数
function varargout = calculator_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;

% --- 添加表达式字符
function appendExpression(handles, val)
global expression;
expression = [expression val];
set(handles.edit_display, 'String', expression);

% --- 数字按钮
function pushbutton0_Callback(hObject, eventdata, handles), appendExpression(handles, '0');
function pushbutton1_Callback(hObject, eventdata, handles), appendExpression(handles, '1');
function pushbutton2_Callback(hObject, eventdata, handles), appendExpression(handles, '2');
function pushbutton3_Callback(hObject, eventdata, handles), appendExpression(handles, '3');
function pushbutton4_Callback(hObject, eventdata, handles), appendExpression(handles, '4');
function pushbutton5_Callback(hObject, eventdata, handles), appendExpression(handles, '5');
function pushbutton6_Callback(hObject, eventdata, handles), appendExpression(handles, '6');
function pushbutton7_Callback(hObject, eventdata, handles), appendExpression(handles, '7');
function pushbutton8_Callback(hObject, eventdata, handles), appendExpression(handles, '8');
function pushbutton9_Callback(hObject, eventdata, handles), appendExpression(handles, '9');

% --- 运算符按钮
function pushbutton_add_Callback(hObject, eventdata, handles), appendExpression(handles, '+');
function pushbutton_sub_Callback(hObject, eventdata, handles), appendExpression(handles, '-');
function pushbutton_mul_Callback(hObject, eventdata, handles), appendExpression(handles, '*');
function pushbutton_div_Callback(hObject, eventdata, handles), appendExpression(handles, '/');
function pushbutton_pow_Callback(hObject, eventdata, handles), appendExpression(handles, '^');

% --- 括号按钮
function pushbutton_left_paren_Callback(hObject, eventdata, handles), appendExpression(handles, '(');
function pushbutton_right_paren_Callback(hObject, eventdata, handles), appendExpression(handles, ')');

% --- 三角函数按钮
function pushbutton_sin_Callback(hObject, eventdata, handles), appendExpression(handles, 'sin(');
function pushbutton_cos_Callback(hObject, eventdata, handles), appendExpression(handles, 'cos(');
function pushbutton_tan_Callback(hObject, eventdata, handles), appendExpression(handles, 'tan(');
function pushbutton_cot_Callback(hObject, eventdata, handles), appendExpression(handles, 'cot(');

% --- 小数点按钮
function pushbutton_dot_Callback(hObject, eventdata, handles)
global expression;
if isempty(expression) || ismember(expression(end), '+-*/')
    appendExpression(handles, '0.');
elseif ~regexp(expression, '\\.\d*$')
    appendExpression(handles, '.');
end

% --- 变量按钮（多项式支持）
function pushbutton_x_Callback(hObject, eventdata, handles), appendExpression(handles, 'x');

% --- 清除按钮
function pushbutton_clear_Callback(hObject, eventdata, handles)
global expression;
expression = '';
set(handles.edit_display, 'String', '');

% --- 等号按钮（计算表达式）
function pushbutton_equal_Callback(hObject, eventdata, handles)
    global expression showFraction;
    try
        % 角度制三角函数替换
        expr_str = expression;
        expr_str = strrep(expr_str, 'sin', 'sind');
        expr_str = strrep(expr_str, 'cos', 'cosd');
        expr_str = strrep(expr_str, 'tan', 'tand');
        expr_str = strrep(expr_str, 'cot', 'cotd');
        
        % 先处理空表达式情况
        if isempty(expr_str)
            set(handles.edit_display, 'String', '');
            return;
        end
        
        % 尝试符号计算（含 x 或其他符号）
        if contains(expr_str, 'x')
            % 尝试转换成符号表达式
            syms x;
            expr_sym = str2sym(expr_str);
            % 简化表达式
            expr_simplified = expand(expr_sym);
            output = char(expr_simplified);
            expression = output;
        else
            % 纯数字计算
            result = eval(expr_str);
            if showFraction
                output = strtrim(char(rats(result)));
            else
                output = num2str(result);
            end
            expression = output;
        end
        
        % 显示结果
        set(handles.edit_display, 'String', output);
    catch ME
        % 出错时显示详细错误信息到命令窗口，便于调试
        fprintf('计算错误: %s\n', ME.message);
        set(handles.edit_display, 'String', '计算错误');
        expression = '';
    end

% --- 分数/小数切换按钮
function pushbutton_toggleFrac_Callback(hObject, eventdata, handles)
global showFraction expression;
showFraction = ~showFraction;
if ~isempty(expression) && ~strcmp(expression, '计算错误')
    try
        expr_str = strrep(expression, 'sin', 'sind');
        expr_str = strrep(expr_str, 'cos', 'cosd');
        expr_str = strrep(expr_str, 'tan', 'tand');
        expr_str = strrep(expr_str, 'cot', 'cotd');
        if contains(expr_str, 'x')
            % 符号表达式不支持分数显示切换，直接显示原表达式
            output = expression;
        else
            val = eval(expr_str);
            if showFraction
                output = strtrim(char(rats(val)));
            else
                output = num2str(val);
            end
        end
        set(handles.edit_display, 'String', output);
        expression = output;
    catch
        % 不做处理
    end
end

% --- edit_display 创建函数（空即可）
function edit_display_CreateFcn(hObject, eventdata, handles)
% 空函数
