% econ.m creates a gui for investigating economic cobweb models with
% varying cost and demand functions for producers with differnt decision
% making processes.
%
% by Tilman C. Dette
% for Math 53, Prof. Alex Barnett


function varargout = econ(varargin)
% ECON M-file for econ.fig
%      ECON, by itself, creates a new ECON or raises the existing
%      singleton*.
%
%      H = ECON returns the handle to a new ECON or the handle to
%      the existing singleton*.
%
%      ECON('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in ECON.M with the given input arguments.
%
%      ECON('Property','Value',...) creates a new ECON or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before econ_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to econ_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help econ

% Last Modified by GUIDE v2.5 05-Dec-2007 11:03:00

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
   'gui_Singleton',  gui_Singleton, ...
   'gui_OpeningFcn', @econ_OpeningFcn, ...
   'gui_OutputFcn',  @econ_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
% End initialization code - DO NOT EDIT


% --- Executes just before econ is made visible.
function econ_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to econ (see VARARGIN)
handles.my.fig = hObject;
handles = myInitialize(handles);
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);



% --- Outputs from this function are returned to the command line.
function varargout = econ_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;




% *************************************************************************
% The following functions are necessary to respond to changes in the Gui.
% You need to understand these to understand how Gui interactions work not
% the computations though. Comments are given at the beginning of each gui
% object type or examploratory for each first object of a group.
% *************************************************************************


% Pop-Up Menues ***********************************************************

% Changes variable in my handle (handles.my) to represent chosen option and
% then updates model and cobweb plot accordingly
% The creation function initializes the corresponding variable in my handle

% Hint:  contents = get(hObject,'String') returns choose... contents as cell array
%        contents{get(hObject,'Value')} returns selected item from
%        chooseProduction
% hObject    handle to choose... (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --- Executes on selection change in chooseProduction.
function chooseProduction_Callback(hObject, eventdata, handles)
handles.my.supply = get(hObject,'Value');
guidata(hObject,handles)
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function chooseProduction_CreateFcn(hObject, eventdata, handles)
handles.my.supply = 2;
set(hObject,'Value', handles.my.supply);
guidata(hObject,handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in chooseDemand.
function chooseDemand_Callback(hObject, eventdata, handles)
handles.my.demand = get(hObject,'Value');
guidata(hObject,handles)
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function chooseDemand_CreateFcn(hObject, eventdata, handles)
handles.my.demand = 3;
set(hObject,'Value', handles.my.demand);
guidata(hObject,handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in chooseMemory.
function chooseMemory_Callback(hObject, eventdata, handles)
handles.my.memory = get(hObject,'Value');
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function chooseMemory_CreateFcn(hObject, eventdata, handles)
handles.my.memory = get(hObject,'Value');
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% Radio Buttons ***********************************************************
%
% Choose whether and if, which agents cobweb graph to display, if agent is
% alone in market...
%
% Hint: get(hObject,'Value') returns toggle state of rb...
% hObject    handle to rb... (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --- Executes on button press in rbAgent1.
function rbAgent1_Callback(hObject, eventdata, handles)
handles.my.cobweb = 1*get(hObject,'Value'); % If selected set cobweb to 1
handles = setModelVar(handles); % update resulting model variables
guidata(hObject,handles); % save updated data in handles
plotMCvsD(handles)   % Update model


% --- Executes on button press in rbAgent2.
function rbAgent2_Callback(hObject, eventdata, handles)
handles.my.cobweb = 2*get(hObject,'Value');
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles)


% --- Executes on button press in rbAgent3.
function rbAgent3_Callback(hObject, eventdata, handles)
handles.my.cobweb = 3*get(hObject,'Value');
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles)


% --- Executes on button press in rbCobwebOff.
function rbCobwebOff_Callback(hObject, eventdata, handles)
if get(hObject,'Value')
   handles.my.cobweb = 0;
end
guidata(hObject,handles);
plotMCvsD(handles)


% --- Executes during object creation, after setting all properties.
% Sets Cobweb to 0 initially
function rbCobwebOff_CreateFcn(hObject, eventdata, handles)
if get(hObject,'Value')
   handles.my.cobweb = 0;
end
guidata(hObject,handles);



% Text Edit Fields ********************************************************

% Update textfied specific variable and redraw model if they affect it or
% the cobweb plot

% Hints: str2double(get(hObject,'String')) returns contents of e... as a double
% hObject    handle to e... (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Demand Variables ********************************************************

function eScaleD_Callback(hObject, eventdata, handles)
handles.my.scaleP = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eScaleD_CreateFcn(hObject, eventdata, handles)
handles.my.scaleP = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eXOff_Callback(hObject, eventdata, handles)
handles.my.xOff = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eXOff_CreateFcn(hObject, eventdata, handles)
handles.my.xOff = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function ePOff_Callback(hObject, eventdata, handles)
handles.my.pOff = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function ePOff_CreateFcn(hObject, eventdata, handles)
handles.my.pOff = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end

% Supply Variables ********************************************************

function ePScale_Callback(hObject, eventdata, handles)
handles.my.scaleC = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function ePScale_CreateFcn(hObject, eventdata, handles)
handles.my.scaleC = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function EminX_Callback(hObject, eventdata, handles)
handles.my.minX = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function EminX_CreateFcn(hObject, eventdata, handles)
handles.my.minX = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eMaxX_Callback(hObject, eventdata, handles)
handles.my.maxX = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eMaxX_CreateFcn(hObject, eventdata, handles)
handles.my.maxX = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eMinC_Callback(hObject, eventdata, handles)
handles.my.minC = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eMinC_CreateFcn(hObject, eventdata, handles)
handles.my.minC = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function ePower_Callback(hObject, eventdata, handles)
handles.my.power = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function ePower_CreateFcn(hObject, eventdata, handles)
handles.my.power = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% El and Iterations for Displayed Model ***********************************

function eElModel_Callback(hObject, eventdata, handles)
handles.my.mEl = str2double(get(hObject,'String'));
plotMCvsD(handles);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eElModel_CreateFcn(hObject, eventdata, handles)
handles.my.mEl = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eModelDiscard_Callback(hObject, eventdata, handles)
handles.my.modelDiscard = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eModelDiscard_CreateFcn(hObject, eventdata, handles)
handles.my.modelDiscard = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eModelN_Callback(hObject, eventdata, handles)
handles.my.modelN = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eModelN_CreateFcn(hObject, eventdata, handles)
handles.my.modelN = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% Cautiousness of Producers ***********************************************

function eC3_Callback(hObject, eventdata, handles)
handles.my.c3 = str2double(get(hObject,'String'));
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eC3_CreateFcn(hObject, eventdata, handles)
handles.my.c3 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eC2_Callback(hObject, eventdata, handles)
handles.my.c2 = str2double(get(hObject,'String'));
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eC2_CreateFcn(hObject, eventdata, handles)
handles.my.c2 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eC1_Callback(hObject, eventdata, handles)
handles.my.c1 = str2double(get(hObject,'String'));
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eC1_CreateFcn(hObject, eventdata, handles)
handles.my.c1 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% Frequency of Producers **************************************************

function eF4_Callback(hObject, eventdata, handles)
handles.my.f4 = str2double(get(hObject,'String'));
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eF4_CreateFcn(hObject, eventdata, handles)
handles.my.f4 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eF3_Callback(hObject, eventdata, handles)
handles.my.f3 = str2double(get(hObject,'String'));
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eF3_CreateFcn(hObject, eventdata, handles)
handles.my.f3 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eF2_Callback(hObject, eventdata, handles)
handles.my.f2 = str2double(get(hObject,'String'));
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eF2_CreateFcn(hObject, eventdata, handles)
handles.my.f2 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eF1_Callback(hObject, eventdata, handles)
handles.my.f1 = str2double(get(hObject,'String'));
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eF1_CreateFcn(hObject, eventdata, handles)
handles.my.f1 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% Initial Output of Producers *********************************************

function eInitX4_Callback(hObject, eventdata, handles)
handles.my.init4 = str2double(get(hObject,'String'));
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eInitX4_CreateFcn(hObject, eventdata, handles)
handles.my.init4 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eInitX3_Callback(hObject, eventdata, handles)
handles.my.init3 = str2double(get(hObject,'String'));
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eInitX3_CreateFcn(hObject, eventdata, handles)
handles.my.init3 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eInitX2_Callback(hObject, eventdata, handles)
handles.my.init2 = str2double(get(hObject,'String'));
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eInitX2_CreateFcn(hObject, eventdata, handles)
handles.my.init2 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eInitX1_Callback(hObject, eventdata, handles)
handles.my.init1 = str2double(get(hObject,'String'));
handles = setModelVar(handles);
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eInitX1_CreateFcn(hObject, eventdata, handles)
handles.my.init1 = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% Choose El ***************************************************************

function eElL_Callback(hObject, eventdata, handles)
handles.my.elL = str2double(get(hObject,'String'));
% handles = setElandX(handles); % Change El and X accordingly
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eElL_CreateFcn(hObject, eventdata, handles)
handles.my.elL = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eElU_Callback(hObject, eventdata, handles)
handles.my.elU = str2double(get(hObject,'String'));
% handles = setElandX(handles);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eElU_CreateFcn(hObject, eventdata, handles)
handles.my.elU = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eElI_Callback(hObject, eventdata, handles)
handles.my.elI = str2double(get(hObject,'String'));
% handles = setElandX(handles);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eElI_CreateFcn(hObject, eventdata, handles)
handles.my.elI = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% Set Iterations **********************************************************

function eN_Callback(hObject, eventdata, handles)
handles.my.N = str2double(get(hObject,'String'));
% handles = setEndInd(handles);
% handles = setElandX(handles);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eN_CreateFcn(hObject, eventdata, handles)
handles.my.N = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



function eNstart_Callback(hObject, eventdata, handles)
handles.my.Ndis = str2double(get(hObject,'String'));
% handles = setEndInd(handles);
% handles = setElandX(handles);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function eNstart_CreateFcn(hObject, eventdata, handles)
handles.my.Ndis = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% periods of memory *******************************************************

function eMemN_Callback(hObject, eventdata, handles)
handles.my.memN = str2double(get(hObject,'String'));
guidata(hObject,handles);
plotMCvsD(handles);

% --- Executes during object creation, after setting all properties.
function eMemN_CreateFcn(hObject, eventdata, handles)
handles.my.memN = str2double(get(hObject,'String'));
guidata(hObject,handles);

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
   set(hObject,'BackgroundColor','white');
end



% Selcect graphs to display ***********************************************

% If selected create a figure and graph the result of the last iteration

% Hint: get(hObject,'Value') returns toggle state of chPrice
% hObject    handle to chPrice (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --- Executes on button press in chPrice.
function chPrice_Callback(hObject, eventdata, handles)
handles.myPlots.price = get(hObject,'Value');

% If selected create a figure for Price at top left corner
if handles.myPlots.price
   scrsz = get(0,'ScreenSize');
   handles.myPlots.Price = figure('Name','Market Price','NumberTitle','off','Position',[1 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2-80]);
   graphPrice(handles);
else
   try
      close(handles.myPlots.Price);
   end
end
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function chPrice_CreateFcn(hObject, eventdata, handles)
handles.myPlots.price = 1;
set(hObject,'Value', handles.myPlots.price);





guidata(hObject,handles);



% --- Executes on button press in chOutput.
function chOutput_Callback(hObject, eventdata, handles)
handles.myPlots.output = get(hObject,'Value');

% If selected create a figure for Output on the bottom left corner
if handles.myPlots.output
   scrsz = get(0,'ScreenSize');
   handles.myPlots.Output = figure('Name','Output of Individual Agents','NumberTitle','off','Position',[1 1 scrsz(3)/2 scrsz(4)/2-80]);
   graphOutput(handles)
else
   try
      close(handles.myPlots.Output);
   end
end
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function chOutput_CreateFcn(hObject, eventdata, handles)
handles.myPlots.output = get(hObject,'Value');
guidata(hObject,handles);



% --- Executes on button press in chProfit.
function chProfit_Callback(hObject, eventdata, handles)
handles.myPlots.profit = get(hObject,'Value');

% If selected create a figure for Profit at the bottom right corner
if handles.myPlots.profit
   scrsz = get(0,'ScreenSize');
   handles.myPlots.Profit = figure('Name','Profit of Individual Agents','NumberTitle','off','Position',[scrsz(3)/2 1 scrsz(3)/2 scrsz(4)/2-80]);
   graphProfit(handles);
else
   try
      close(handles.myPlots.Profit);
   end
end
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function chProfit_CreateFcn(hObject, eventdata, handles)
handles.myPlots.profit = get(hObject,'Value');
guidata(hObject,handles);



% Button for graph update *************************************************
% hObject    handle to iterateAndGraph (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --- Executes on button press in iterateAndGraph.
function iterateAndGraph_Callback(hObject, eventdata, handles)
temp = get(hObject,'String');
set(hObject,'String', 'Busy Iterating');
drawnow;
handles = iterate(handles);
set(hObject,'String', temp);
guidata(hObject,handles);
drawnow;
drawPlots(handles);

% end of functions to respond to Gui **************************************
% *************************************************************************



% Initialize **************************************************************

function H = myInitialize(handles)
handles = setEndInd(handles);
handles = setElandX(handles);
plotMCvsD(handles);
handles = iterate(handles);
if handles.myPlots.price
   scrsz = get(0,'ScreenSize');
   handles.myPlots.Price = figure('Name','Market Price','NumberTitle','off','Position',[1 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2-80]);
   graphPrice(handles);
end


H = handles;
% *************************************************************************

function H = setEndInd(handles)
% Set endInd equal to the index of the outcomes we use
My = handles.my;
handles.my.endInd = (My.N+2-(My.N-My.Ndis)):(My.N+1);

H = handles;

function H = setElandX(handles)
% With elL, elI, elU, and the initial x values set el and X
% vectorize el
handles.my.el = handles.my.elL:handles.my.elI:handles.my.elU;
% Initialize X accordingly
handles.my.X = ones (5, length(handles.my.el), handles.my.N+1);

H = handles;
% *************************************************************************



% The Price Functions *****************************************************
function P = Price(X, el, handles)
% Use the selected Price function
switch handles.my.demand
   case 1
      P = Price1(X, el, handles);
   case 2
      P = Price2(X, el, handles);
   case 3
      P = Price3(X, el, handles);
   case 4
      P = Price4(X, el, handles);
end

function P = Price1(X, el, handles)
% Demand 1 (perfect substitute to constant product)
%
% Consumers will spend constant P (just below substitute price, given by
% scalar) only until their constant demand is satisfied. So for x > scalar,
% P = 0, help received from Alex Barnett
P = el.*(X <= handles.my.scaleP);

function P = Price2(X, el, handles)
% Demand 2 (constant slope)
%
% The Scalar determines P(0), el the slope
P = max((handles.my.scaleP - el.*X), 0);

function P = Price3(X, el, handles)
% Demand 3 (isoelastic demand without upper and lower Limit)
%
% In Ozonaki's model elasticity is the same everywhere
P = max(handles.my.scaleP./(X).^el, 0);

function P = Price4(X, el, handles)
My = handles.my;
% Demand 4 (isoelastic demand with upper and lower Limit)
%
% As in Ozonaki's model elasticity is the same everywhere but the curve is
% shifted in to prevent the unrealistic infinit limits (by xOff and pOff)
P = max(My.scaleP./(X + My.xOff).^el - My.pOff, 0);
% *************************************************************************



% The Supply Functions ****************************************************
function C = Cost(X, handles)
switch handles.my.supply
   case 1
      C = Cost1(X, handles);
   case 2
      C = Cost2(X, handles);
   case 3
      C = Cost3(X, handles);
   case 4
      C = Cost4(X, handles);
   case 5
      C = Cost5(X, handles);
end

function S = Supply(P, handles)
switch handles.my.supply
   case 1
      S = Supply1(P, handles);
   case 2
      S = Supply2(P, handles);
   case 3
      S = Supply3(P, handles);
   case 4
      S = Supply4(P, handles);
   case 5
      S = Supply5(P, handles);
end

% Cost 1 (constant marginal cost - linear)
%
% Constant returns to scale until maximum capacity is reached
% So if MC is less than P firms choose full capacity, else they choose 0.
function C = Cost1(X, handles)
C = handles.my.scaleC*X + 1e+10*(X > handles.my.maxX);
function S = Supply1(P, handles)
S = handles.my.maxX*(handles.my.scaleC <= P);

% Cost 2 (quadratic cost function)
%
% In Ozonko's model, this function gives a linear marginal cost functionfunction C = Cost(X, handles)
function C = Cost2(X, handles)
C = handles.my.scaleC/2*(X).^2;
function S = Supply2(P, handles)
S = P./handles.my.scaleC;

% Cost 3 (quadratic cost function)
%
% As in Ozonko's model this function gives a linear marginal cost function
% but in addition allows for minimum cost (i.e. fixed cost) and min output
function C = Cost3(X, handles)
C = handles.my.scaleC/2*(max(X-handles.my.minX, 0)).^2 + handles.my.minC;
function S = Supply3(P, handles)
S = P./handles.my.scaleC + handles.my.minX;

% Cost 4 (cost function to the power >= 2)
function C = Cost4(X, handles)
C = handles.my.scaleC/handles.my.power*X.^handles.my.power;
function S = Supply4(P, handles)
S = (P./handles.my.scaleC).^(1/(handles.my.power-1));

% Cost 5 (cost function to the power >= 2)
% with increasing then decreasing returns to scale (most realistic). Thus
% if power is even, we multiply the downward sloping part by -1
% So firms again produce such that MC = P, but we also need MC' > 0, and
% P*X >= Cost(X)
function C = Cost5(X, handles)
My = handles.my;
C = My.scaleC/My.power*(((X-My.minX).^My.power).*(X >= My.minX) - ((abs(X-My.minX)).^My.power).*(X < My.minX) + (abs(My.minX)).^My.power);
function S = Supply5(P, handles)
SupX5   = @(P) (handles.my.minX + (P./handles.my.scaleC).^(1/(handles.my.power-1)));
S = SupX5(P).*(SupX5(P).*P >= Cost5(SupX5(P), handles));

function S = RatSupply(X, handles)
% Rational producer function, based on the choices of the others
% xOptimum = @(x1, x2) solve(differentiate(Price(x1, x2, xOpt)*xOpt - Cost(xOpt), xOpt), xOpt);
% As the above function is not possible (as ML cannot differentiate like
% this) we simply assume the rational producer to only think at the margin:
f4 = handles.my.f4;
if f4 % only if nonzero to avoid unnecessary calc
   Predict   = @(X) Supply(Price(X, handles.my.el, handles), handles);
   Rational1 = @(X) Predict(X + f4*Predict(X));
   Rational2 = @(X) Predict(X + f4*Rational1(X));
   Rational3 = @(X) Predict(X + f4*Rational2(X));
   Rational4 = @(X) Predict(X + f4*Rational3(X));
   S = Predict(X + f4*Rational4(X));
else
   S = 0*X;
end
% *************************************************************************



% !!!The Iteration!!! *****************************************************
function H = iterate(handles)

% Intiate El and X as intended for iteration
handles = setEndInd(handles);
handles = setElandX(handles);

My = handles.my;
X = My.X;
% set initial output
X(1,:,1) = My.f1*My.init1*ones(1,length(My.el),1);
X(2,:,1) = My.f2*My.init1*ones(1,length(My.el),1);
X(3,:,1) = My.f3*My.init1*ones(1,length(My.el),1);
X(4,:,1) = My.f4*My.init1*ones(1,length(My.el),1);

% Let the fun begin
tic;
output =@ (f,X,p,q,c,op) max((X(p,:,q) + c*(f*op - X(p,:,q))), zeros(1,length(My.el),1));
for n = 1:My.N
   % Determine old Price using old x values
   P = Price(X(1,:,n) + X(2,:,n) + X(3,:,n) + X(4,:,n), My.el, handles);
   if n == 1
      opt = Supply(P, handles);
   else
      opt = optimize(P, X(5,:,2:n), n, handles);
   end
   % With this price determine the next x values
   % Use the max function to prevent negative output
   X(:,:,n+1) = [output(My.f1,X,1,n,My.c1,opt);
      output(My.f2,X,2,n,My.c2,opt);
      output(My.f3,X,3,n,My.c3,opt);
      max(My.f4*RatSupply(output(My.f1,X,1,n,My.c1,opt) + output(My.f2,X,2,n,My.c2,opt) + output(My.f3,X,3,n,My.c3,opt), handles), zeros(1,length(My.el),1));
      P];
end
toc

% Shift Price vector as right now P(t-1) is lined up with X(t)
for n = 1:My.N
   X(5,:,n) = X(5,:,n+1);
end
X(5,:,My.N+1) = Price(X(1,:,My.N+1) + X(2,:,My.N+1) + X(3,:,My.N+1) + X(4,:,My.N+1), My.el, handles);

% Save our results in my handle
handles.my.X = X;

% return Handles
H = handles;
% *************************************************************************



% MC vs. Demand Plot ******************************************************
% To illustrate the chosen model in our window for [0 10 0 10]
function plotMCvsD(handles)
% Set Focus to axis on the gui
axes(handles.modelPlot)
hold off; % discard previous plots
P = 0:0.01:10; % our choice of P
X = 0:0.01:10; % our choice of X
% Plot average cost in green
plot(X, Cost(X, handles)./X, 'g');
hold on;
% Plot the Supply for P in red, discretly as it can be discontiued
plot(Supply(P, handles), P, '.r', 'MarkerSize', 3);
% Plot the Demand at X in blue
plot(X, Price(X, handles.my.mEl, handles), 'b');
% Set axis, but turn indexes off.
drawCobweb(handles);
axis([0 10 0 10]);
set(gca,'XTick', []);
set(gca,'YTick', []);
% *************************************************************************


% Draw Cobwebplot for Model ***********************************************
function H = setModelVar(handles)
switch handles.my.cobweb;
   case 1
      handles.my.cM = handles.my.c1;
      handles.my.initM = handles.my.init1;
   case 2
      handles.my.cM = handles.my.c2;
      handles.my.initM = handles.my.init2;
   case 3
      handles.my.cM = handles.my.c3;
      handles.my.initM = handles.my.init3;
end
H = handles;

function drawCobweb(handles)
% Plot only if cobwebplot has been chosen
if handles.my.cobweb
   % Create cobweb series
   X = zeros(2, 2*handles.my.modelN + 1);
   X(:, 1) = [0 ; handles.my.initM];
   for n = 1:2:(2*handles.my.modelN - 1)
      X(:, n+1) = [Price(X(2, n), handles.my.mEl, handles); X(2, n)];
      if n == 1
         opt = Supply(X(1, n+1), handles);
      else
         opt = optimize(X(1, n+1), reshape(X(1, 2:2:n-1),1,1,[]), (n+1)/2, handles);
      end
      X(:, n+2) = [X(1, n+1); max(X(2,n+1) + handles.my.cM*(opt - X(2,n+1)), 0)];
   end
   plot(X(2, (1 + 2*handles.my.modelDiscard):end), X(1, (1 + 2*handles.my.modelDiscard):end), '--mo');
end
% *************************************************************************



% Estimate Optimal Output given a history of prices ***********************
function O = optimize(P, oldP, n, handles)
switch handles.my.memory
   case 1 % no memory
      O = Supply(P, handles);
   case 2 % n periods of memory (average price)
      O = Supply((P + sum(oldP(1,:,max(1, n-handles.my.memN):n-1),3))./min(n, handles.my.memN+1), handles);
   case 3 % infinit memory (average price)
      O = Supply((P + sum(oldP(1,:,1:n-1),3))./n, handles); % use average Price (for memory)
   case 4 % "weighted" memory with n periods of memory
      O = Supply((2*P + sum(oldP(1,:,max(1, n-handles.my.memN):n-1),3))./min(n+1, handles.my.memN+2), handles);
   case 5 % "weighted" infinit memory
      O = Supply((2*P + sum(oldP(1,:,1:n-1),3))./(n+1), handles);
end
% *************************************************************************



% Price, Output, and Profit Graphs ****************************************
% Graph selected iterations for 1/el
function drawPlots(handles)
if handles.myPlots.price
   graphPrice(handles);
end
if handles.myPlots.output
   graphOutput(handles);
end
if handles.myPlots.profit
   graphProfit(handles);
end


function graphPrice(handles)
Nend = handles.my.N-handles.my.Ndis;
figure(handles.myPlots.Price) % Focus on Price figure
hold off;
% Graph Price versus 1/elasticity
tic;
% Convert Data to plotable arrays
xs = zeros(length(handles.my.el), Nend);
for iter = 1:length(handles.my.el)
   xs(iter,:) = handles.my.el(iter)*ones(1, Nend);
end
xs = reshape(xs, 1, []);
ys = reshape(handles.my.X(5, :, handles.my.endInd), 1, []);
% Graph all points for a certain el
plot (xs, ys, '.', 'MarkerSize', 3);
% Label Graph
title(strcat('Market Price after ', num2str(handles.my.Ndis), ' for ', num2str(handles.my.N), ' Iterations for Different Elasticities'));
xlabel('1/(elasticity of demand)');
ylabel('Price');
toc


function graphOutput(handles)
Nend = handles.my.N-handles.my.Ndis;
figure(handles.myPlots.Output) % Focus on Output figure
hold off;
% Graph the different choosen outputs
tic;
% Convert Data to plotable arrays
xs = zeros(length(handles.my.el), Nend);
for iter = 1:length(handles.my.el)
   xs(iter,:) = handles.my.el(iter)*ones(1,Nend);
end
xs = reshape(xs, 1, []);
ys1 = reshape(handles.my.X(1, :, handles.my.endInd), 1, [])./handles.my.f1;
ys2 = reshape(handles.my.X(2, :, handles.my.endInd), 1, [])./handles.my.f2;
ys3 = reshape(handles.my.X(3, :, handles.my.endInd), 1, [])./handles.my.f3;
ys4 = reshape(handles.my.X(4, :, handles.my.endInd), 1, [])./handles.my.f4;
% Graph all points for a certain el
plot (xs, ys4, 'r.', 'MarkerSize', 3); hold on;
plot (xs, ys3, 'y.', 'MarkerSize', 3);
plot (xs, ys2, 'g.', 'MarkerSize', 3);
plot (xs, ys1, 'b.', 'MarkerSize', 3);
% Label Graph
title(strcat('Individual Market Output after ', num2str(handles.my.Ndis), ' for ', num2str(handles.my.N), ' Iterations for Different Elasticities'));
xlabel('1/(elasticity of demand)');
ylabel('Individual output');
toc


function graphProfit(handles)
Nend = handles.my.N-handles.my.Ndis;
figure(handles.myPlots.Profit) % Focus on Output figure
hold off;
% Graph the firms average Profit over the Nend Iterations
% Avg. Profit = 1/Nend*sum(p*q - cost(q))
tic;
% Calculate profits for each iteration of the Nend Iterations for each firm
pr1 = reshape(handles.my.X(5,:,handles.my.endInd).*handles.my.X(1,:,handles.my.endInd) - handles.my.f1*Cost(handles.my.X(1,:,handles.my.endInd)./handles.my.f1, handles), length(handles.my.el), Nend)./handles.my.f1;
pr2 = reshape(handles.my.X(5,:,handles.my.endInd).*handles.my.X(2,:,handles.my.endInd) - handles.my.f2*Cost(handles.my.X(2,:,handles.my.endInd)./handles.my.f2, handles), length(handles.my.el), Nend)./handles.my.f2;
pr3 = reshape(handles.my.X(5,:,handles.my.endInd).*handles.my.X(3,:,handles.my.endInd) - handles.my.f3*Cost(handles.my.X(3,:,handles.my.endInd)./handles.my.f3, handles), length(handles.my.el), Nend)./handles.my.f3;
pr4 = reshape(handles.my.X(5,:,handles.my.endInd).*handles.my.X(4,:,handles.my.endInd) - handles.my.f4*Cost(handles.my.X(4,:,handles.my.endInd)./handles.my.f4, handles), length(handles.my.el), Nend)./handles.my.f4;
% Draw the three profits as a function of el
plot (handles.my.el, sum(pr4, 2)'./Nend, 'r.', 'MarkerSize', 3); hold on;
plot (handles.my.el, sum(pr3, 2)'./Nend, 'y.', 'MarkerSize', 3);
plot (handles.my.el, sum(pr2, 2)'./Nend, 'g.', 'MarkerSize', 3);
plot (handles.my.el, sum(pr1, 2)'./Nend, 'b.', 'MarkerSize', 3);
% Draw zero profit line
plot (handles.my.el, zeros(1, length(handles.my.el)), 'k');
% Label Graph
title(strcat('Firms avg. Profit after ', num2str(handles.my.Ndis), ' for ', num2str(handles.my.N), ' Iterations'));
xlabel('1/(elasticity of demand)');
ylabel('Avg. Profit');
toc
% *************************************************************************