function varargout = lifegenesis(varargin)
% LIFEGENESIS play LifeGenesis
%   LifeGenesis is based on the remarkable Life simulation rules 
%   developed by the mathematician John Horton Conway.  
%   LifeGenesis includes both a Life simulator and a game based 
%   on Life that you can play against the computer.
%
%   When your life become bore, play game or develope game! (Kyaw Tun)
%

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

% Last Modified by GUIDE v2.5 19-Mar-2003 23:49:32

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @lifegenesis_OpeningFcn, ...
                   'gui_OutputFcn',  @lifegenesis_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin & isstr(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 lifegenesis is made visible.
function lifegenesis_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 lifegenesis (see VARARGIN)

% Choose default command line output for lifegenesis
handles.output = hObject;

handles.GridWidth = 24;
handles.nGrid = 15;
handles.D = 5;
handles.MessageHeigth = 18;
handles.UserColor = [0 0 1]; % blue color
handles.ComputerColor = [1 0 0]; % red color
handles.DefaultColor = get(0,'defaultUicontrolBackgroundColor');
handles.User = 1;
handles.Computer = 2;
handles.nIniCell = 18*2;
handles.GameData = zeros(handles.nGrid,handles.nGrid);
handles.GenerationPause = 1;

% Update handles structure
guidata(hObject, handles);

figure1_ResizeFcn(hObject, eventdata, handles)
set(handles.textMessage, 'String', 'Click File New game to start');



% UIWAIT makes lifegenesis wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = lifegenesis_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;


% --------------------------------------------------------------------
function mnuFileNewGame_Callback(hObject, eventdata, handles)
% hObject    handle to mnuFileNewGame (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --- distribute initial cells randomly
handles.GameData = zeros(handles.nGrid,handles.nGrid);
rand('state',sum(100*clock));
X = ceil(rand(1,handles.nIniCell)*handles.nGrid);
Y = ceil(rand(1,handles.nIniCell)*handles.nGrid);
for k = 1:length(X)
    if mod(k,2) == 1
        handles.GameData(X(k),Y(k)) = handles.User;
    else
        handles.GameData(X(k),Y(k)) = handles.Computer;
    end
end
Refresh(handles);    
RunGame(handles);


% ======================
function RunGame(handles)

Job = 'User1Create';
while ishandle(handles.axesMain)
    set(handles.figure1, 'Name', 'MATLAB LifeGenesis - Tournament in progress')
    switch Job
        case 'User1Create'
            % get user input cell to create a cell
            set(handles.textMessage, 'String', 'Select an empty cell (blue).')
            [X, Y, Btn] = ginput(1, 'wizard'); % get input cell
            x = ceil(X * handles.nGrid); % block no
            y = ceil(Y * handles.nGrid);
            if handles.GameData(handles.nGrid-y+1, x) ~= 0
                waitfor(warndlg('Select an empty cell (blue)', 'Life Genesis'));
                continue
            end    
            ChangeColor(x,y,handles.nGrid,handles.DefaultColor,handles.UserColor);
            handles.GameData(handles.nGrid-y+1, x) = handles.User;
            guidata(handles.axesMain, handles);
            Job = 'User1Delete';
        case 'User1Delete'
            % get user input cell to delete a cell
            set(handles.textMessage, 'String', 'Select red cell to be deleted.')
            [X, Y, Btn] = ginput(1, 'wizard'); % get input cell
            x = ceil(X * handles.nGrid); % block no
            y = ceil(Y * handles.nGrid);
            if handles.GameData(handles.nGrid-y+1, x) ~= handles.Computer
                waitfor(warndlg('Select a red cell', 'Life Genesis'));
                continue
            end    
            ChangeColor(x,y,handles.nGrid,handles.ComputerColor,handles.DefaultColor);
            handles.GameData(handles.nGrid-y+1, x) = 0;
            guidata(handles.axesMain, handles);     
            
            % --- Generation
            set(handles.textMessage, 'String', 'Click for User2 turn.');
            ginput(1,'generation');            
            [UC, CC, GameData, DeletedGameData] = Generation(handles, handles.GameData);
            set(handles.textMessage, 'String', 'Generation. Deleting cells ...');
            pause(handles.GenerationPause);
            handles.GameData = DeletedGameData;
            guidata(handles.axesMain, handles);     
            Refresh(handles);
            set(handles.textMessage, 'String', 'Generation. Creating cells ...');
            pause(handles.GenerationPause);
            handles.GameData = GameData;
            guidata(handles.axesMain, handles);     
            Refresh(handles);   
            if UC == 0
                Job = 'User2Won';
            elseif CC == 0
                Job = 'User1Won';
            else
                Job = 'User2Create';
            end
        case 'User2Create'
            %set(handles.textMessage, 'String', 'Click for User2 turn.');
            %ginput(1,'mouse');            
            %set(handles.textMessage, 'String', 'Computer is creating a cell ...');
            %[Best,x,y] = ComputerCreate(handles);
            %pause(handles.GenerationPause);
            %handles.GameData(Best) = handles.Computer;
            %guidata(handles.axesMain, handles);     
            %ChangeColor(x,y,handles.nGrid,handles.DefaultColor,handles.ComputerColor);
            set(handles.textMessage, 'String', 'Select an empty cell (red).')
            [X, Y, Btn] = ginput(1, 'wizard'); % get input cell
            x = ceil(X * handles.nGrid); % block no
            y = ceil(Y * handles.nGrid);
            if handles.GameData(handles.nGrid-y+1, x) ~= 0
                waitfor(warndlg('Select an empty cell (red)', 'Life Genesis'));
                continue
            end    
            ChangeColor(x,y,handles.nGrid,handles.DefaultColor,handles.ComputerColor);
            handles.GameData(handles.nGrid-y+1, x) = handles.Computer;
            guidata(handles.axesMain, handles);
            
            Job = 'User2Delete';
        case 'User2Delete'
            %set(handles.textMessage, 'String', 'Computer is deleting a cell ...');
            %[Best,x,y] = ComputerDelete(handles);
            %pause(handles.GenerationPause);
            %handles.GameData(Best) = 0;
            %guidata(handles.axesMain, handles);     
            %ChangeColor(x,y,handles.nGrid,handles.UserColor,handles.DefaultColor);
            
            % --- Generation
            %pause(1)
            %[UC, CC, GameData, DeletedGameData] = Generation(handles, handles.GameData);
            %set(handles.textMessage, 'String', 'Generation. Deleting cells ...');
            %pause(handles.GenerationPause);
            %handles.GameData = DeletedGameData;
            %guidata(handles.axesMain, handles);     
            %Refresh(handles);
            %set(handles.textMessage, 'String', 'Generation. Creating cells ...');
            %pause(handles.GenerationPause);
            %handles.GameData = GameData;
            %guidata(handles.axesMain, handles);     
            %Refresh(handles); 
            set(handles.textMessage, 'String', 'Select blue cell to be deleted.')
            [X, Y, Btn] = ginput(1, 'wizard'); % get input cell
            x = ceil(X * handles.nGrid); % block no
            y = ceil(Y * handles.nGrid);
            if handles.GameData(handles.nGrid-y+1, x) ~= handles.User
                waitfor(warndlg('Select a blue cell', 'Life Genesis'));
                continue
            end    
            ChangeColor(x,y,handles.nGrid,handles.UserColor,handles.DefaultColor);
            handles.GameData(handles.nGrid-y+1, x) = 0;
            guidata(handles.axesMain, handles);     
            
            % --- Generation
            set(handles.textMessage, 'String', 'Click for User1 turn.');
            ginput(1,'generation');            
            [UC, CC, GameData, DeletedGameData] = Generation(handles, handles.GameData);
            set(handles.textMessage, 'String', 'Generation. Deleting cells ...');
            pause(handles.GenerationPause);
            handles.GameData = DeletedGameData;
            guidata(handles.axesMain, handles);     
            Refresh(handles);
            set(handles.textMessage, 'String', 'Generation. Creating cells ...');
            pause(handles.GenerationPause);
            handles.GameData = GameData;
            guidata(handles.axesMain, handles);     
            Refresh(handles);
            if UC == 0
                Job = 'User2Won';
            elseif CC == 0
                Job = 'User1Won';
            else
                Job = 'User1Create';
            end
            set(handles.textMessage, 'String', 'Select an empty cell to create.');
        case 'User1Won'
            waitfor(msgbox('User1 won.', 'Life Genesis'))
            set(handles.textMessage, 'String', 'Game over');
            break
        case 'User2Won'
            waitfor(msgbox('User2 won.', 'Life Genesis'))
            set(handles.textMessage, 'String', 'Game over.');
            break
        otherwise
            break; % unexpected
    end
end
set(handles.figure1, 'Name', 'MATLAB LifeGenesis')



% ===================================================
function Refresh(handles)

axes(handles.axesMain);
cla;
N = handles.nGrid;
UserCount = 0; 
ComputerCount = 0;
for kx = 1:N
    for ky = 1:N
        if handles.GameData(ky,kx) == handles.User
            hd = rectangle('Position', [kx-1, N-ky, 1, 1] ./ N, ...
                'FaceColor', handles.UserColor); 
            UserCount = UserCount + 1;
        elseif handles.GameData(ky,kx) == handles.Computer
            hd = rectangle('Position', [kx-1, N-ky, 1, 1] ./ N, ...
                'FaceColor', handles.ComputerColor);            
            ComputerCount = ComputerCount + 1;
        end
    end
end
set(handles.textCount, 'String', [num2str(UserCount), ':', num2str(ComputerCount)]);



% ==========================================
function [UserCount, ComputerCount, GameData, DeletedGameData] = Generation(handles, GameData)
% render generation according to life genesis rule
%
% 1. A living cell with fewer than two neighbors dies of isolation. 
% 2. A living cell with more than three neighbors dies of overcrowding.
% 3. New life is generated in an empty square with exactly three neighbors.

User = handles.User;
Com = handles.Computer;

% --- count neighbors
UserNb = zeros(size(GameData));
ComNb = zeros(size(GameData));
for x = 1:size(GameData,1)
    for y = 1:size(GameData,2)
        % there are eight neighbor to count
        if x ~= 1 % left
            UserNb(x,y) = UserNb(x,y) + (GameData(x-1,y) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x-1,y) == Com);
        end
        if x ~= size(GameData,2) % right
            UserNb(x,y) = UserNb(x,y) + (GameData(x+1,y) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x+1,y) == Com);
        end
        if y ~= size(GameData,1) % top
            UserNb(x,y) = UserNb(x,y) + (GameData(x,y+1) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x,y+1) == Com);
        end
        if y ~= 1 % bottom
            UserNb(x,y) = UserNb(x,y) + (GameData(x,y-1) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x,y-1) == Com);
        end
        if x ~= 1 & y ~= size(GameData,1) % left top
            UserNb(x,y) = UserNb(x,y) + (GameData(x-1,y+1) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x-1,y+1) == Com);
        end
        if x ~= size(GameData,2) & y ~= size(GameData,1) % right top
            UserNb(x,y) = UserNb(x,y) + (GameData(x+1,y+1) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x+1,y+1) == Com);
        end
        if x ~= 1 & y ~= 1 % left bottom
            UserNb(x,y) = UserNb(x,y) + (GameData(x-1,y-1) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x-1,y-1) == Com);
        end
        if x ~= size(GameData,2) & y ~= 1 % right bottom
            UserNb(x,y) = UserNb(x,y) + (GameData(x+1,y-1) == User);
            ComNb(x,y) = ComNb(x,y) + (GameData(x+1,y-1) == Com);
        end
    end
end

% --- Determine cell to delete
for x = 1:size(GameData,1)
    for y = 1:size(GameData,2)
        % 1. A living cell with fewer than two neighbors dies of isolation. 
        % 2. A living cell with more than three neighbors dies of overcrowding.
        Neighbor = UserNb(x,y) + ComNb(x,y);
        if Neighbor < 2 | Neighbor > 3
            GameData(x,y) = 0;
        end
    end
end
DeletedGameData = GameData;

% --- Determine cell to create
CreateCell = zeros(size(GameData));
for x = 1:size(GameData,1)
    for y = 1:size(GameData,2)
        % 3. New life is generated in an empty square with exactly three neighbors.
        if GameData(x,y) == 0 & (UserNb(x,y) + ComNb(x,y) == 3)
            if UserNb(x,y) >= 2
                GameData(x,y) = User;
            else
                GameData(x,y) = Com;
            end
        end
    end
end

UserCount = length(find(GameData==User));
ComputerCount = length(find(GameData==Com));


% --------------------------------------------------------------------
function mnuHelpHelp_Callback(hObject, eventdata, handles)
% hObject    handle to mnuHelpHelp (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

web(which('LifeGenesis.htm'))


% =======================
function [Best, x, y] = ComputerCreate(handles)
% create so the computer count is large

Data = handles.GameData;
ComCount = zeros(size(Data));

for x = 1:size(Data,2)
    for y = 1:size(Data,1)
        if Data(x,y) == 0 % empty cell
            GameData = Data;
            GameData(x,y) = handles.Computer;
            [UserCount, ComputerCount, GameData, DeletedGameData] = Generation(handles, GameData);
            ComCount(x,y) = ComputerCount;
        end
    end
end

[foo, Best] = max(ComCount(:));
X = ceil(Best/size(Data,1));
Y = mod(Best,size(Data,1));
x = X;
y = size(Data,1)-Y+1;



% =======================
function [Best, x, y] = ComputerDelete(handles)
% delete so that the use count is least

Data = handles.GameData;
UserCount = zeros(size(Data));

for x = 1:size(Data,2)
    for y = 1:size(Data,1)
        if Data(x,y) == handles.User % empty cell
            GameData = Data;
            GameData(x,y) = 0;
            [UCount, ComputerCount, GameData, DeletedGameData] = Generation(handles, GameData);
            UserCount(x,y) = UCount;
        end
    end
end

if all(UserCount==0) % 
    [Y, X] = find(Data==handles.User);
    Y = Y(1); X = X(1);    
    Best = ((X-1)*size(Data,1))+Y;
else
	UserCount(find(UserCount==0)) = inf;
	[foo, Best] = min(UserCount(:));
end
X = ceil(Best/size(Data,1));
Y = mod(Best,size(Data,1));
x = X;
y = size(Data,1)-Y+1;



% =========================================================================
function [out1,out2,out3] = ginput(arg1, PointerShape)
%GINPUT Graphical input from mouse.
%   [X,Y] = GINPUT(N) gets N points from the current axes and returns 
%   the X- and Y-coordinates in length N vectors X and Y.  The cursor
%   can be positioned using a mouse (or by using the Arrow Keys on some 
%   systems).  Data points are entered by pressing a mouse button
%   or any key on the keyboard except carriage return, which terminates
%   the input before N points are entered.
%
%   [X,Y] = GINPUT gathers an unlimited number of points until the
%   return key is pressed.
% 
%   [X,Y,BUTTON] = GINPUT(N) returns a third result, BUTTON, that 
%   contains a vector of integers specifying which mouse button was
%   used (1,2,3 from left) or ASCII numbers if a key on the keyboard
%   was used.
%   
%   This file was modified to change pointer shape
%   These custom shape are available: 'wizard', 'generation', 'mouse'

%   Copyright 1984-2002 The MathWorks, Inc. 
%   $Revision: 5.32 $  $Date: 2002/04/14 13:20:49 $

PointerShapeHotSpot = [16, 16];
if nargin < 2 % edit KT
    PointerShape = 'fullcrosshair';
else
    if isequal(PointerShape, 'wizard')
        PointerShape = [1 NaN 1 NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;NaN 1 NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;1 NaN 1 NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;NaN 1 NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;1 NaN 1 1 1 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN 1 1 1 NaN NaN NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN 1 1 1 NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 1 1 NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 1 1 NaN NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 1 NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1];
        PointerShapeHotSpot = [1 1];
    elseif isequal(PointerShape, 'generation')
        PointerShape = [NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN 1 1 1 1 2 1 NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN 1 2 2 2 2 2 1 NaN NaN NaN NaN;NaN NaN NaN NaN NaN 1 1 1 1 2 1 NaN NaN NaN NaN NaN;NaN NaN 1 NaN NaN NaN NaN NaN NaN 1 NaN NaN 1 1 1 NaN;NaN 1 2 1 NaN NaN NaN NaN NaN NaN NaN NaN 1 2 1 NaN;1 2 2 2 1 NaN NaN NaN NaN NaN NaN NaN 1 2 1 NaN;NaN 1 2 1 NaN NaN NaN NaN NaN NaN NaN NaN 1 2 1 NaN;NaN 1 2 1 NaN NaN NaN NaN NaN NaN NaN NaN 1 2 1 NaN;NaN 1 2 1 NaN NaN NaN NaN NaN NaN NaN 1 2 2 2 1;NaN 1 2 1 NaN NaN NaN NaN NaN NaN NaN NaN 1 2 1 NaN;NaN 1 1 1 NaN NaN 1 NaN NaN NaN NaN NaN NaN 1 NaN NaN;NaN NaN NaN NaN NaN 1 2 1 1 1 1 1 NaN NaN NaN NaN;NaN NaN NaN NaN 1 2 2 2 2 2 2 1 NaN NaN NaN NaN;NaN NaN NaN NaN NaN 1 2 1 1 1 1 1 NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN];
    elseif isequal(PointerShape, 'mouse')
        PointerShape = [NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN 1 1 1 NaN NaN NaN NaN NaN NaN;NaN NaN NaN NaN 1 1 1 2 2 1 1 1 1 NaN NaN NaN;NaN NaN NaN 1 2 2 2 2 2 1 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 1 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 1 2 2 2 1 NaN NaN;NaN NaN NaN 1 1 1 1 1 1 1 1 1 1 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 2 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 2 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 2 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 2 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 2 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 2 2 2 2 1 NaN NaN;NaN NaN NaN 1 2 2 2 2 2 2 2 2 2 1 NaN NaN;NaN NaN NaN NaN 1 1 1 1 1 1 1 1 1 NaN NaN NaN;NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN];
    else
        PointerShape = 'fullcrosshair';
    end
end
out1 = []; out2 = []; out3 = []; y = [];
c = computer;
if ~strcmp(c(1:2),'PC') 
   tp = get(0,'TerminalProtocol');
else
   tp = 'micro';
end

if ~strcmp(tp,'none') & ~strcmp(tp,'x') & ~strcmp(tp,'micro'),
   if nargout == 1,
      if nargin == 1,
         out1 = trmginput(arg1);
      else
         out1 = trmginput;
      end
   elseif nargout == 2 | nargout == 0,
      if nargin == 1,
         [out1,out2] = trmginput(arg1);
      else
         [out1,out2] = trmginput;
      end
      if  nargout == 0
         out1 = [ out1 out2 ];
      end
   elseif nargout == 3,
      if nargin == 1,
         [out1,out2,out3] = trmginput(arg1);
      else
         [out1,out2,out3] = trmginput;
      end
   end
else
   
   fig = gcf;
   figure(gcf);
   
   if nargin == 0
      how_many = -1;
      b = [];
   else
      how_many = arg1;
      b = [];
      if  isstr(how_many) ...
            | size(how_many,1) ~= 1 | size(how_many,2) ~= 1 ...
            | ~(fix(how_many) == how_many) ...
            | how_many < 0
         error('Requires a positive integer.')
      end
      if how_many == 0
         ptr_fig = 0;
         while(ptr_fig ~= fig)
            ptr_fig = get(0,'PointerWindow');
         end
         scrn_pt = get(0,'PointerLocation');
         loc = get(fig,'Position');
         pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)];
         out1 = pt(1); y = pt(2);
      elseif how_many < 0
         error('Argument must be a positive integer.')
      end
   end
   
   % Remove figure button functions
   state = uisuspend(fig);
   pointer = get(gcf,'pointer');
   if ischar(PointerShape)
       set(gcf,'pointer',PointerShape);
   else
       set(gcf,'pointer', 'custom', 'PointerShapeCData', PointerShape, ...
           'PointerShapeHotSpot',PointerShapeHotSpot)
   end
   fig_units = get(fig,'units');
   char = 0;
   
   while how_many ~= 0
      % Use no-side effect WAITFORBUTTONPRESS
      waserr = 0;
      try
	keydown = wfbp;
      catch
	waserr = 1;
      end
      if(waserr == 1)
         if(ishandle(fig))
            set(fig,'units',fig_units);
	    uirestore(state);
            error('Interrupted');
         else
            error('Interrupted by figure deletion');
         end
      end
      
      ptr_fig = get(0,'CurrentFigure');
      if(ptr_fig == fig)
         if keydown
            char = get(fig, 'CurrentCharacter');
            button = abs(get(fig, 'CurrentCharacter'));
            scrn_pt = get(0, 'PointerLocation');
            set(fig,'units','pixels')
            loc = get(fig, 'Position');
            pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)];
            set(fig,'CurrentPoint',pt);
         else
            button = get(fig, 'SelectionType');
            if strcmp(button,'open')
               button = b(length(b));
            elseif strcmp(button,'normal')
               button = 1;
            elseif strcmp(button,'extend')
               button = 2;
            elseif strcmp(button,'alt')
               button = 3;
            else
               error('Invalid mouse selection.')
            end
         end
         pt = get(gca, 'CurrentPoint');
         
         how_many = how_many - 1;
         
         if(char == 13) % & how_many ~= 0)
            % if the return key was pressed, char will == 13,
            % and that's our signal to break out of here whether
            % or not we have collected all the requested data
            % points.  
            % If this was an early breakout, don't include
            % the <Return> key info in the return arrays.
            % We will no longer count it if it's the last input.
            break;
         end
         
         out1 = [out1;pt(1,1)];
         y = [y;pt(1,2)];
         b = [b;button];
      end
   end
   
   uirestore(state);
   set(fig,'units',fig_units);
   
   if nargout > 1
      out2 = y;
      if nargout > 2
         out3 = b;
      end
   else
      out1 = [out1 y];
   end
   
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function key = wfbp
%WFBP   Replacement for WAITFORBUTTONPRESS that has no side effects.

fig = gcf;
current_char = [];

% Now wait for that buttonpress, and check for error conditions
waserr = 0;
try
  h=findall(fig,'type','uimenu','accel','C');   % Disabling ^C for edit menu so the only ^C is for
  set(h,'accel','');                            % interrupting the function.
  keydown = waitforbuttonpress;
  current_char = double(get(fig,'CurrentCharacter')); % Capturing the character.
  if~isempty(current_char) & (keydown == 1)           % If the character was generated by the 
	  if(current_char == 3)                       % current keypress AND is ^C, set 'waserr'to 1
		  waserr = 1;                             % so that it errors out. 
	  end
  end
  
  set(h,'accel','C');                                 % Set back the accelerator for edit menu.
catch
  waserr = 1;
end
drawnow;
if(waserr == 1)
   set(h,'accel','C');                                % Set back the accelerator if it errored out.
   error('Interrupted');
end

if nargout>0, key = keydown; end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% ===============================================
function hd = ChangeColor(x,y,n,OldColor,NewColor)
% change OldColor to NewColor gradually
% x, y      poisition
% n         size, handles.nGrid

hd = rectangle('Position', [x-1, y-1, 1, 1] ./ n, 'FaceColor', OldColor);

dColor = NewColor - OldColor;
N = 10;

for k = 1:N
    pause(0.1)
    set(hd, 'FaceColor', OldColor+dColor.*k./N);
end


% --------------------------------------------------------------------
function mnuHelpAbout_Callback(hObject, eventdata, handles)
% hObject    handle to mnuHelpAbout (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

msgbox(sprintf([...
        '                            MATLAB LifeGenesis\n', ...
        '                               Version 1.0\n', ...
        '\n\n', ...
        '  Freeware available at http://www.geocities.com/kyawtuns\n', ...
        '\n', ...
        '                           Auther: KyawTun']), ...
        'About LifeGenesis')
% Play sound during load
filename = [getenv('windir'), '\Media\tada.wav'];
if exist(filename, 'file')
    [Y, FS] = wavread(filename);
    wavplay(Y, FS);
end


% --- Executes when figure1 window is resized.
function figure1_ResizeFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

GridWidth = handles.GridWidth;
D = handles.D;
nGrid = handles.nGrid;

set(handles.figure1, 'Units', 'Pixels');
Pos = get(handles.figure1, 'Position');
set(hObject, 'Position', ...
    [Pos(1),Pos(2),GridWidth*nGrid+2*D,GridWidth*nGrid+4*D+handles.MessageHeigth]);
set(handles.axesMain, 'XTick', [[1:nGrid]./nGrid]);
set(handles.axesMain, 'YTick', [[1:nGrid]./nGrid]);
set(handles.axesMain, 'Position', ...
    [D, 3*D+handles.MessageHeigth, GridWidth*nGrid, GridWidth*nGrid]);
set(handles.axesMain, 'Color', handles.DefaultColor);
set(handles.textMessage, 'Position', [D, D, GridWidth*nGrid, handles.MessageHeigth]);
set(handles.textCount, 'Position', [GridWidth*nGrid-50, D, 50, handles.MessageHeigth]);
