function vote92(action)

%VOTE92  GUI based analysis of 1992 Presidential election results
%
%  Synopsis:  vote92
%
%  VOTE92 produces an interactive window allowing the analysis
%  of the 1992 presidential election results.  The user is
%  allowed to re-allocate Perot's vote to Clinton and Bush
%  and display the resulting electoral vote outcome.  For any
%  postulated outcome, the states switching for the actual
%  outcome to the hypothesized outcome can be highlighted.  In
%  addition, the user can query the map for detailed election
%  results on a state-by-state basis.  The script is
%  executed by entering VOTE92.

%  Copyright 1996-1998 by Systems Planning and Analysis, Inc. and The MathWorks, Inc.
% $Revision: 1.10 $
%  Written by:  E. Byrns, E. Brown



if nargin == 0;   action = 'initialize';   end


if strcmp(action,'initialize')

     [savehndl,rawdata] = votepanl;

%  Load up the seeded united states map and legend.

     load usamtx

%  Compute the Excess Electoral Vote Function and plot

     [clintonexcss,percents] = votepntl(rawdata);
     [votes,voteclr] = votecalc(rawdata(:,1:3),sum(rawdata(:,4:5)')');
     axes(savehndl(1));
     plot(percents,clintonexcss);

%  Add the line slider to the excess votes function

  	 xlim = get(gca,'Xlim');
  	 ylim = get(gca,'Ylim');
     middle = xlim(1)+diff(xlim)/2;
	 linehndl = plot(middle*[1 1],ylim,':','EraseMode','xor', ...
	                 'ButtonDownFcn', 'vote92(''down'');');


%  Construct the actual results map and display
%  Disable the standard mapping toolbox buttondown callbacks

    axes(savehndl(2));
	[latlim,lonlim]=limitm(map,maplegend);

	range = max(latlim)-min(latlim);
	parallels = [min(latlim)+range/6 max(latlim)-range/6];

	axesm('MapProjection','eqaconic','MapLatLimit',latlim,'MapLonLimit',lonlim,...
			'mapparallels',parallels)
	set(gca,'ButtonDownFcn','')
	meshm(map,maplegend,[2 40],'ButtonDownFcn','')
	colormap([0 0 0; 0 1 1; 1 1 .5; voteclr]);
    title(['Winner by State (Red: Bush, Blue: Clinton)'],'Color','black');
	axis tight
	
%  Save the necessary data for later retrieval

     set(gcf,'UserData', savehndl);
     set(savehndl(3),'UserData',rawdata);
     set(savehndl(4),'UserData',states);
     set(savehndl(5),'UserData',map);
     set(savehndl(6),'UserData',maplegend);
     set(savehndl(7),'UserData',num2str(50) );
 	 set(savehndl(8),'UserData',[votes votes]);
	 set(savehndl(9),'UserData',voteclr);

     set(gcf,'Visible','on')

elseif strcmp(action,'down')  % User clicks on line slider

%  Change the line slider width and set the appropriate
%  window properties.

	hndl = get(gcf,'CurrentObject');
	set(hndl,'UserData',gca);
	set(hndl,'Visible','off','LineWidth', 5);
	set(hndl,'Visible','on')
    set(gcf,'WindowButtonUpFcn', 'vote92(''up'');', ...
            'WindowButtonMotionFcn', 'vote92(''move'');');

elseif strcmp(action,'move')  %  User moves the line slider

%  Retrieve the necessary data

	 hndl = get(gcf,'CurrentObject');
     savehndl = get(gcf,'UserData');
     rawdata  = get(savehndl(3),'UserData');

%  Get the current cursor point and axis limits

     lineaxis = get(hndl,'Parent');
     point = get(lineaxis,'CurrentPoint');
  	 xlim  = get(lineaxis,'Xlim');
	 ylim  = get(lineaxis,'Ylim');

%  Update the slider line display

     newpt    = min(max(point(1,1),xlim(1)),xlim(2));
     set(hndl, 'Xdata', newpt*[1 1]);

%  Compute the new popular vote given the specified split of
%  Perot votes.

     Bvotes = rawdata(:,1) + (1-newpt/100)*rawdata(:,3);
     Cvotes = rawdata(:,2) + (newpt/100)*rawdata(:,3);

%  Compute the electoral votes given the new popular vote

	 [votes,voteclr] = votecalc([Bvotes Cvotes],sum(rawdata(:,4:5)')');
	 rslts = sum(votes);

%  Update the displays

	 set(savehndl(9),'String',int2str(rslts(2)));
	 set(savehndl(10),'String',int2str(rslts(1)));
     if rslts(1) > rslts(2)
	      	 set(savehndl(11),'String','Winner:  Bush');
     else
	      	 set(savehndl(11),'String','Winner:  Clinton');
	 end

%  Display a rounded version of the Perot vote percent

	 set(savehndl(12),'String',num2str(newpt,4));
	 set(savehndl(13),'String',num2str(100-newpt,4));

%  Save the election results data

     set(savehndl(7),'UserData',num2str(newpt,4));
 	 set(savehndl(8),'UserData',[Bvotes Cvotes votes]);
	 set(savehndl(9),'UserData',voteclr);

elseif strcmp(action,'up')  %  Line slider object is released

%  Change the line slider width and set the appropriate
%  window properties.

    hndl = get(gcf,'CurrentObject');
	axishndl = get(hndl,'UserData');
    set(gcf, 'WindowButtonUpFcn','', 'WindowButtonMotionFcn','');
    set(hndl,'Visible','off');
    set(hndl, 'LineWidth', 1, 'ButtonDownFcn', 'vote92(''down'');');
    set(hndl,'Visible','on');
    axes(axishndl);

%  Display the new electoral results map.

%  Retrieve the required data

    savehndl   = get(gcf,'UserData');
    rawdata    = get(savehndl(3),'UserData');
    states     = get(savehndl(4),'UserData');
    map        = get(savehndl(5),'UserData');
	maplegend  = get(savehndl(6),'UserData');
    perotprcnt = get(savehndl(7),'UserData');
    votedata   = get(savehndl(8),'UserData');
    voteclr    = get(savehndl(9),'UserData');

%  Draw the electoral votes map

	colormap([0 0 0; 0 1 1; 1 1 .5; voteclr]);
    title(['Clinton Receives ',perotprcnt,'% of Perot Vote']);

elseif strcmp(action,'show')  % Results button is pressed

%  Retrieve the required data

    savehndl   = get(gcf,'UserData');
    voteclr    = get(savehndl(9),'UserData');

%  Set the results colormap

    clrmap = [0  0  0; 0  1  1; 1  1  .5; voteclr];
    colormap(clrmap);  refresh

elseif strcmp(action,'switch')  %  Switched button is pressed

%  Retrieve the required data

    savehndl   = get(gcf,'UserData');
    rawdata    = get(savehndl(3),'UserData');
    states     = get(savehndl(4),'UserData');
    map        = get(savehndl(5),'UserData');
	maplegend  = get(savehndl(6),'UserData');
    perotprcnt = get(savehndl(7),'UserData');
    votedata   = get(savehndl(8),'UserData');
    voteclr    = get(savehndl(9),'UserData');

%  Compute the highlighed colormap for the map display

    votes     = votedata(:,3:4);
    switched  = (~rawdata(:,4:5)) & votes;
    switched  = sum(switched')';
    indx      = find(switched==1);
    if ~isempty(indx)
	     voteclr(indx,1:3) = 0.5*voteclr(indx,1:3);
    end

%  Set the highlighted colormap

    clrmap = [0  0  0; 0  1  1; 1  1  .5; voteclr];
    colormap(clrmap); refresh

end


%**************************************************************************
%**************************************************************************
%**************************************************************************


function [savehndl,rawdata] = votepanl

%VOTEPANL  Creates the interface objects for the VOTE92 GUI
%
%  The data for the operation of this demo is stored in
%  various user data positions in the interface objects.

%  Copyright 1996-1998 by Systems Planning and Analysis, Inc. and The MathWorks, Inc.
% $Revision: 1.10 $
%  Written by:  E. Byrns, E. Brown


%  1992 Election data results
%  Source:  America Votes 20:  A Handbook of Contemporary
%           American Election Statistics.
%           Scammon, Richard and McGillivray Alice.  p. 7.
%           Washington D.C.:  1993.  Congressional Quarterly.
%
%     Popular vote (%)         Electoral Vote     % State and Seed
%     Bush, Clinton, Perot     Bush, Clinton

rawdata =[
47.6	40.9	10.8	9	0       % Alabama			1
39.5	30.3	28.4	3	0       % Alaska			2
38.5	36.5	23.8	8	0       % Arizona			3
35.5	53.2	10.4	0	6       % Arkansas			4
32.6	46.0	20.5	0	54      % California		5
35.9	40.1	23.3	0	6       % Colorado			6
35.8	42.2	21.6	0	8       % Connecticut		7
35.3	43.5	20.4	0	3       % Delaware			8
40.9	39.0	19.8	25	0       % Florida 			9
42.9	43.5	13.3	0	13      % Georgia	   		10
36.7	48.1	14.2	0	4       % Hawaii			11
42.0	28.4	27.0	4	0       % Idaho				12
34.3	48.6	16.6	0	22      % Illinois			13
42.9	36.8	19.8	12	0       % Indiana			14
37.3	43.3	18.7	0	7       % Iowa				15
38.9	33.7	27.0	6	0       % Kansas			16
41.3	44.8	13.7	0	8       % Kentucky			17
41.0	45.6	11.8	0	9       % Louisiana			18
30.4	38.8	30.4	0	4       % Maine				19
35.6	49.8	14.2	0	12      % Maryland			20
29.0	47.5	22.7	0	10      % Massachusetts		21
36.4	43.8	19.3	0	18      % Michigan			22
31.9	43.5	24.0	0	10      % Minnesota			23
49.7	40.8	8.7		7	0       % Mississippi		24
33.9	44.1	21.7	0	11      % Missouri			25
35.1	37.6	26.1	0	3       % Montana			26
46.8	29.4	23.6	5	0       % Nebraska			27
34.7	37.4	26.2	0	4       % Nevada			28
37.6	38.9	22.6	0	4       % New Hampshire		29
40.6	43.0	15.6	0	15      % New Jersey		30
37.3	45.9	16.1	0	5       % New Mexico		31
33.9	49.7	15.7	0	33      % New York			32
43.4	42.7	13.7	14	0       % North Carolina	33
44.2	32.2	23.1	3	0       % North Dakota		34
38.3	40.2	21.0	0	21      % Ohio				35
42.6	34.0	23.0	8	0       % Oklahoma			36
32.5	42.5	24.2	0	7       % Oregon			37
36.1	45.1	18.2	0	23      % Pennsylvania		38
29.0	47.0	23.2	0	4       % Rhode Island		39
48.0	39.9	11.5	8	0       % South Carolina	40
40.7	37.1	21.8	3	0       % South Dakota		41
42.4	47.1	10.1	0	11      % Tennessee			42
40.6	37.1	22.0	32	0       % Texas				43
43.4	24.7	27.3	5	0       % Utah				44
30.4	46.1	22.8	0	3       % Vermont			45
45.0	40.6	13.8	13	0       % Virginia			46
32.0	43.4	23.7	0	11      % Washington		47
35.4	48.4	15.9	0	5       % West Virginia		48
36.8	41.1	21.5	0	11      % Wisconsin			49
39.6	34.0	25.8	3	0       % Wyoming			50
9.1		84.6	4.3		0	3       % District of Columbia	51
];


%  Compute the Pixel and Font Scaling Factors so
%  GUI figure windows and fonts look OK across all platforms

PixelFactor = guifactm('pixels');
FontScaling =  guifactm('fonts');

%  Construct the gui figure window

figure('Units','Points',...
    'Resize','on', 'Name','1992 Election Data',...
    'Numbertitle','off',...
	'Renderer','zbuffer', 'Visible','off');

%  Enforce V5 color defaults

colordef(gcf,'white')
figclr = get(gcf,'Color');

%  Excess Electoral Votes axes

savehndl(1) = axes('Position',[0.10   0.10   0.50   0.25], 'Box', 'on', ...
                   'Xlim', [0 100], 'Ylim', [-400 400], ...
	               'NextPlot', 'add'); grid off
xlabel('Percent of Perot Vote For Clinton');
ylabel('Excess Electoral Votes')
title(['DRAG DOTTED LINE TO ALLOCATE PEROT VOTERS']);



%  Map axes

savehndl(2) = axes('Units', 'normalized',...
                   'Position', [0.10   0.45   0.60   0.45], 'Box', 'on');

%  Switched vote button

savehndl(3) = uicontrol(gcf, 'Style','Push',...
			'Units','Normalized', 'Position',[0.80   0.80   0.15   0.09], ...
			'String','Switched', 'CallBack','vote92(''switch'')' );

%  Electoral results button

savehndl(4) = uicontrol(gcf, 'Style','Push',...
			'Units','Normalized', 'Position',[0.80   0.65   0.15   0.09], ...
			'String','Results', 'CallBack','vote92(''show'')' );

%  Exit button

savehndl(5) = uicontrol(gcf, 'Style','Push',...
			'Units','Normalized', 'Position',[0.80   0.50   0.15   0.09], ...
			'String','Exit', 'CallBack','close' );


%  Title text

savehndl(6) = uicontrol(gcf, 'Style','Text', ...
          'Units', 'Normalized', 'Position',[0.71   0.28   0.25   0.03], ...
		  'String','Actual    Potential   % Perot Vote',...
		  'HorizontalAlignment','left',...
		  'BackgroundColor',figclr, 'ForegroundColor','black' );

savehndl(7) = uicontrol(gcf, 'Style', 'Text', ...
          'Units', 'Normalized', 'Position',[0.63   0.23   0.14   0.03], ...
		  'String', 'Clinton        368',...
		  'HorizontalAlignment', 'left',...
		  'BackgroundColor',figclr, 'ForegroundColor','black' );

savehndl(8) = uicontrol(gcf, 'Style', 'Text', ...
          'Units', 'Normalized', 'Position',[0.63   0.18   0.14   0.03], ...
		  'String', 'Bush           168',...
		  'HorizontalAlignment', 'left',...
		  'BackgroundColor',figclr, 'ForegroundColor','black' );


%  Clinton potential electoral votes

savehndl(9) = uicontrol(gcf, 'Style', 'Text', ...
              'Units', 'Normalized', 'Position',[0.80   0.23   0.05   0.03], ...
		      'String', '368',...
		      'HorizontalAlignment', 'right',...
		      'BackgroundColor',figclr, 'ForegroundColor','black' );

%  Bush potential electoral votes

savehndl(10) = uicontrol(gcf, 'Style', 'Text', ...
              'Units', 'Normalized', 'Position',[0.80   0.18   0.05   0.03], ...
		      'String', '168',...
		      'HorizontalAlignment', 'right',...
		      'BackgroundColor',figclr, 'ForegroundColor','black' );

%  Winner banner

savehndl(11) = uicontrol(gcf, 'Style', 'Text', ...
              'Units', 'Normalized', 'Position',[0.63   0.13   0.20   0.03], ...
		      'String', 'Winner:  Clinton',...
		      'HorizontalAlignment', 'left',...
		      'BackgroundColor',figclr, 'ForegroundColor','blue' );

%  Clinton percent of Perot votes

savehndl(12) = uicontrol(gcf, 'Style', 'Text', ...
              'Units', 'Normalized', 'Position',[0.87   0.23   0.06   0.03], ...
		      'String', '50',...
		      'HorizontalAlignment', 'right',...
		      'BackgroundColor',figclr, 'ForegroundColor','black' );

%  Bush percent of Perot votes

savehndl(13) = uicontrol(gcf, 'Style', 'Text', ...
              'Units', 'Normalized', 'Position',[0.87   0.18   0.06   0.03], ...
		      'String', '50',...
		      'HorizontalAlignment', 'right',...
		      'BackgroundColor',figclr, 'ForegroundColor','black' );



%**************************************************************************
%**************************************************************************
%**************************************************************************


function [votes,colormap] = votecalc(votedata,evtotal)

%VOTECALC  Calculates the election results for VOTE92
%
%  VOTECALC  inputs the election data in the form of Bush,
%  Clinton and Perot popular vote percentages and the
%  total electoral votes in a state.  The function outputs
%  a vote result matrix indicating whether Bush or Clinton
%  recieved the corresponding electoral votes.  In addition,
%  a colormap matrix is computed for the states indicating
%  if Bush wins (red) or Clinton wins (Blue).

%  Copyright 1996-1998 by Systems Planning and Analysis, Inc. and The MathWorks, Inc.
% $Revision: 1.10 $
%  Written by:  E. Byrns, E. Brown


result = votedata(:,1) > votedata(:,2);    % Bush state wins
winners = [result ~result];                % State winner matrix
votes   = winners .* evtotal(:,ones(1,2));

colormap = [result 0*result ~result];


%**************************************************************************
%**************************************************************************
%**************************************************************************


function  [clintonexcss,percents] = votepntl(rawdata)

%VOTEPNTL  Computes the spectrum of potential election outcomes for VOTE92
%
%  VOTEPNTL computes the Clinton excess electoral vote function
%  as the percentage of Perot's votes assigned to Clinton varies
%  from 0 to 100%.

%  Copyright 1996-1998 by Systems Planning and Analysis, Inc. and The MathWorks, Inc.
% $Revision: 1.10 $
%  Written by:  E. Byrns, E. Brown


percents = 100:-1:0;
needed  = 269;

for i = 1:length(percents)


%  Compute the new popular vote given the specified split of
%  Perot votes.

      Bvotes = rawdata(:,1) + (1-percents(i)/100)*rawdata(:,3);
      Cvotes = rawdata(:,2) + (percents(i)/100)*rawdata(:,3);

%  Determine the electoral vote outcome for this hypothetical
%  election.

      votes   = votecalc([Bvotes Cvotes],sum(rawdata(:,4:5)')');
      rslts   = sum(votes);

%  Compute the Clinton excess electoral votes

      clintonexcss(i) = rslts(1,2) - needed;
end


%**************************************************************************
%**************************************************************************
%**************************************************************************
