No BSD License  

Highlights from
flatRubiks

image thumbnail
from flatRubiks by Trent Russi
A Rubiks Cube unwrapped onto a 2D plane.

flatRubiks(flag)
function flatRubiks(flag)
%flatRubiks  Flattened out Rubik's Cube
%
%  flatRubiks opens a new game.  There are many menu options
%  that change the look of the cube.  Also there is a builtin
%  solver, Copyright Mark Jaeys.
%
%  flatRubiks -HELP opens the help in the MATLAB helpbrowser.
%
%  flatRubiks -ABOUT opens a message box with credits.
%
%  Copyright 2005, Trent Michael Russi.

if nargin==1
    switch flag
        case {'about','-About','-about','-ABOUT'}
            menuAbout;
        case {'help','-help','-Help','-HELP'}
            menuHelp;
        otherwise
            error('Incorrect call');
    end
    return
end

%constants
scale = 10;
cubeSize = 5*scale;
spaceSize = 0.5*scale;
backColor = [1 1 1];
border = 5*scale;

%create figure
figH = figure('position',[100 100 2*border+15*cubeSize+8*spaceSize 2*border+11*cubeSize+6*spaceSize], ...
              'menubar','none', ...
              'name','Flat Rubik''s Cube', ...
              'numbertitle','off',...
              'color',backColor, ...
              'resize','off');

%create axes
axesH = axes('parent',figH, ...
             'units','pixels', ...
             'position',[0 0 2*border+15*cubeSize+8*spaceSize 2*border+11*cubeSize+6*spaceSize], ...
             'xlim',[-border-4*cubeSize-2*spaceSize border+11*cubeSize+6*spaceSize], ...
             'ylim',[-border-4*cubeSize-2*spaceSize border+7*cubeSize+4*spaceSize], ...
             'visible','off','buttondownfcn',{@smallBDF},...
             'nextplot','add');
         
%start to build cube
ph = zeros(15,12);
ph(1:3,1:3) = buildPatch([-4*cubeSize-2*spaceSize 4*cubeSize+2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(4:6,1:3) = buildPatch([-4*cubeSize-2*spaceSize 4*cubeSize+2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(7:9,1:3) = buildPatch([-4*cubeSize-2*spaceSize 0],cubeSize,spaceSize,[0 1 0]);
ph(10:12,1:3) = buildPatch([-4*cubeSize-2*spaceSize -4*cubeSize-2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(13:15,1:3) = buildPatch([-4*cubeSize-2*spaceSize -4*cubeSize-2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(1:3,4:6) = buildPatch([0 8*cubeSize+4*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(4:6,4:6) = buildPatch([0 4*cubeSize+2*spaceSize],cubeSize,spaceSize,[1 1 0]);
ph(7:9,4:6) = buildPatch([0 0],cubeSize,spaceSize,[1 0 0]);
ph(10:12,4:6) = buildPatch([0 -4*cubeSize-2*spaceSize],cubeSize,spaceSize,[1 1 1]);
ph(13:15,4:6) = buildPatch([0 -8*cubeSize-4*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(1:3,7:9) = buildPatch([4*cubeSize+2*spaceSize 4*cubeSize+2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(4:6,7:9) = buildPatch([4*cubeSize+2*spaceSize 4*cubeSize+2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(7:9,7:9) = buildPatch([4*cubeSize+2*spaceSize 0],cubeSize,spaceSize,[0 0 1]);
ph(10:12,7:9) = buildPatch([4*cubeSize+2*spaceSize -4*cubeSize-2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(13:15,7:9) = buildPatch([4*cubeSize+2*spaceSize -4*cubeSize-2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(1:3,10:12) = buildPatch([12*cubeSize+6*spaceSize 0],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(4:6,10:12) = buildPatch([8*cubeSize+4*spaceSize 4*cubeSize+2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(7:9,10:12) = buildPatch([8*cubeSize+4*spaceSize 0],cubeSize,spaceSize,[1 0.5 0]);
ph(10:12,10:12) = buildPatch([8*cubeSize+4*spaceSize -4*cubeSize-2*spaceSize],cubeSize,spaceSize,[0.5 0.5 0.5]);
ph(13:15,10:12) = buildPatch([-8*cubeSize-4*spaceSize 0],cubeSize,spaceSize,[0.5 0.5 0.5]);


%set callbacks
set(ph(6,6),'buttondownfcn',{@orientIt,1});
set(ph(7,[6 7]),'buttondownfcn',{@orientIt,1});
set(ph(9,[1 12]),'buttondownfcn',{@orientIt,1});
set(ph(12,4),'buttondownfcn',{@orientIt,1});
set(ph(4,6),'buttondownfcn',{@orientIt,2});
set(ph(7,[9 10]),'buttondownfcn',{@orientIt,2});
set(ph(9,[3 4]),'buttondownfcn',{@orientIt,2});
set(ph(10,4),'buttondownfcn',{@orientIt,2});
set(ph(6,4),'buttondownfcn',{@orientIt,4});
set(ph(7,[3 4]),'buttondownfcn',{@orientIt,4});
set(ph(9,[9 10]),'buttondownfcn',{@orientIt,4});
set(ph(12,6),'buttondownfcn',{@orientIt,4});
set(ph(4,4),'buttondownfcn',{@orientIt,3});
set(ph(7,[1 12]),'buttondownfcn',{@orientIt,3});
set(ph(9,[6 7]),'buttondownfcn',{@orientIt,3});
set(ph(10,6),'buttondownfcn',{@orientIt,3});
set(ph([6 7 12],5),'buttondownfcn',{@orientIt,5});
set(ph(9,11),'buttondownfcn',{@orientIt,5});
set(ph([4 9 10],5),'buttondownfcn',{@orientIt,6});
set(ph(7,11),'buttondownfcn',{@orientIt,6});
set(ph([8 8 8 8],[3 4 9 10]),'buttondownfcn',{@orientIt,7});
set(ph([8 8 8 8],[1 6 7 12]),'buttondownfcn',{@orientIt,8});
set(ph(5,4),'buttondownfcn',{@orientIt,9});
set(ph(7,2),'buttondownfcn',{@orientIt,9});
set(ph(9,8),'buttondownfcn',{@orientIt,9});
set(ph(11,6),'buttondownfcn',{@orientIt,9});
set(ph(5,6),'buttondownfcn',{@orientIt,10});
set(ph(7,8),'buttondownfcn',{@orientIt,10});
set(ph(9,2),'buttondownfcn',{@orientIt,10});
set(ph(11,4),'buttondownfcn',{@orientIt,10});
set(ph(5,5),'buttondownfcn',{@orientIt,11});
set(ph(11,5),'buttondownfcn',{@orientIt,11});
set(ph(8,2),'buttondownfcn',{@orientIt,12});
set(ph(8,8),'buttondownfcn',{@orientIt,12});
set(ph(8,5),'buttondownfcn',{@orientIt,13});
set(ph(8,11),'buttondownfcn',{@orientIt,13});
phbuttondf = get(ph,'buttondownfcn');
setappdata(figH,'phbuttondf',phbuttondf);



%setappdata
setappdata(figH,'ph',ph);
setappdata(figH,'cubeSize',cubeSize);
setappdata(figH,'spaceSize',spaceSize);
setappdata(figH,'animation',10);

colors = struct('color',cell(size(ph)),'face',cell(size(ph)));
for i1=1:prod(size(ph))
    faceColor = get(ph(i1),'faceColor');
    colors(i1).color = faceColor;
    if faceColor==[0 1 0]
        colors(i1).face = 1;
    elseif faceColor==[1 1 0]
        colors(i1).face = 2;
    elseif faceColor==[1 0 0]
        colors(i1).face = 3;
    elseif faceColor==[1 1 1]
        colors(i1).face = 4;
    elseif faceColor==[0 0 1]
        colors(i1).face = 5;
    elseif faceColor==[1 0.5 0]
        colors(i1).face = 6;
    else
        colors(i1).face = 0;
    end
end
setappdata(figH,'colors',colors);

%covers
patch([-5*cubeSize -5*cubeSize -0.5*cubeSize -0.5*cubeSize],...
      [-0.5*cubeSize -5*cubeSize -5*cubeSize -0.5*cubeSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);
patch([-5*cubeSize -5*cubeSize -0.5*cubeSize -0.5*cubeSize],...
      [3.5*cubeSize+2*spaceSize 9*cubeSize 9*cubeSize 3.5*cubeSize+2*spaceSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);
patch([3.5*cubeSize+2*spaceSize 3.5*cubeSize+2*spaceSize 13*cubeSize 13*cubeSize],...
      [-0.5*cubeSize -5*cubeSize -5*cubeSize -0.5*cubeSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);
patch([3.5*cubeSize+2*spaceSize 3.5*cubeSize+2*spaceSize 13*cubeSize 13*cubeSize],...
      [3.5*cubeSize+2*spaceSize 9*cubeSize 9*cubeSize 3.5*cubeSize+2*spaceSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);
patch([-6*cubeSize -6*cubeSize -4.5*cubeSize-2*spaceSize -4.5*cubeSize-2*spaceSize],...
      [4*cubeSize -cubeSize -cubeSize 4*cubeSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);
patch([11.5*cubeSize+6*spaceSize 11.5*cubeSize+6*spaceSize 14*cubeSize 14*cubeSize],...
      [4*cubeSize -cubeSize -cubeSize 4*cubeSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);
patch([-cubeSize -cubeSize 4*cubeSize 4*cubeSize],...
      [7.5*cubeSize+4*spaceSize 9*cubeSize 9*cubeSize 7.5*cubeSize+4*spaceSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);
patch([-cubeSize -cubeSize 4*cubeSize 4*cubeSize],...
      [-4.5*cubeSize-2*spaceSize -6*cubeSize -6*cubeSize -4.5*cubeSize-2*spaceSize],...
      [5 5 5 5],backColor,...
      'EdgeAlpha',0);

%lines
xc = 1.5*cubeSize+spaceSize;
yc = xc;
r1 = 3*cubeSize+spaceSize+i*(1.5*cubeSize+spaceSize);
r2 = 4*cubeSize+2*spaceSize+i*(1.5*cubeSize+spaceSize);
r3 = 5*cubeSize+3*spaceSize+i*(1.5*cubeSize+spaceSize);
theta1 = linspace(angle(r1),pi/2-angle(r1));
theta2 = linspace(angle(r2),pi/2-angle(r2));
theta3 = linspace(angle(r3),pi/2-angle(r3));
r1=abs(r1); r2=abs(r2); r3=abs(r3);
z=10*ones(1,100);
plot3(r1*cos(theta1)+xc,r1*sin(theta1)+yc,z,'r:');
plot3(r2*cos(theta2)+xc,r2*sin(theta2)+yc,z,'r:');
plot3(r3*cos(theta3)+xc,r3*sin(theta3)+yc,z,'r:');
plot3(-r1*cos(theta1)+xc,r1*sin(theta1)+yc,z,'r:');
plot3(-r2*cos(theta2)+xc,r2*sin(theta2)+yc,z,'r:');
plot3(-r3*cos(theta3)+xc,r3*sin(theta3)+yc,z,'r:');
plot3(r1*cos(theta1)+xc,-r1*sin(theta1)+yc,z,'r:');
plot3(r2*cos(theta2)+xc,-r2*sin(theta2)+yc,z,'r:');
plot3(r3*cos(theta3)+xc,-r3*sin(theta3)+yc,z,'r:');
plot3(-r1*cos(theta1)+xc,-r1*sin(theta1)+yc,z,'r:');
plot3(-r2*cos(theta2)+xc,-r2*sin(theta2)+yc,z,'r:');
plot3(-r3*cos(theta3)+xc,-r3*sin(theta3)+yc,z,'r:');
  
%buttons
buttons = zeros(18,1);
buttons(1) = text('string','\leftarrow',...
                  'position',[-4.75*cubeSize 0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveX,3,1});
buttons(2) = text('string','\leftarrow',...
                  'position',[-4.75*cubeSize 1.5*cubeSize+spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveX,2,1});
buttons(3) = text('string','\leftarrow',...
                  'position',[-4.75*cubeSize 2.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveX,1,1});
buttons(4) = text('string','\rightarrow',...
                  'position',[11.25*cubeSize+6*spaceSize 0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveX,3,2});
buttons(5) = text('string','\rightarrow',...
                  'position',[11.25*cubeSize+6*spaceSize 1.5*cubeSize+spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveX,2,2});
buttons(6) = text('string','\rightarrow',...
                  'position',[11.25*cubeSize+6*spaceSize 2.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveX,1,2});
buttons(7) = text('string',' \uparrow ',...
                  'position',[0.5*cubeSize 7.5*cubeSize+4*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,1,1});
buttons(8) = text('string',' \uparrow ',...
                  'position',[1.5*cubeSize+spaceSize 7.5*cubeSize+4*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,2,1});
buttons(9) = text('string',' \uparrow ',...
                  'position',[2.5*cubeSize+2*spaceSize 7.5*cubeSize+4*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,3,1});
buttons(10) = text('string',' \downarrow ',...
                  'position',[0.5*cubeSize -4.5*cubeSize-2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,1,2});
buttons(11) = text('string',' \downarrow ',...
                  'position',[1.5*cubeSize+spaceSize -4.5*cubeSize-2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,2,2});
buttons(12) = text('string',' \downarrow ',...
                  'position',[2.5*cubeSize+2*spaceSize -4.5*cubeSize-2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,3,2});
buttons(13) = text('string',' \uparrow ',...
                  'position',[4.25*cubeSize+2*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,1});
buttons(14) = text('string',' \uparrow ',...
                  'position',[5.25*cubeSize+3*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,1});
buttons(15) = text('string',' \uparrow ',...
                  'position',[6.25*cubeSize+4*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,1});
buttons(16) = text('string',' \downarrow ',...
                  'position',[4.25*cubeSize+2*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,2});
buttons(17) = text('string',' \downarrow ',...
                  'position',[5.25*cubeSize+3*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,2});
buttons(18) = text('string',' \downarrow ',...
                  'position',[6.25*cubeSize+4*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,2});
buttons(19) = text('string',' \downarrow ',...
                  'position',[-3.5*cubeSize-2*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,1},...
                  'visible','off');
buttons(20) = text('string',' \downarrow ',...
                  'position',[-2.5*cubeSize-2*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,1},...
                  'visible','off');
buttons(21) = text('string',' \downarrow ',...
                  'position',[-1.5*cubeSize-2*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,1},...
                  'visible','off');
buttons(22) = text('string',' \downarrow ',...
                  'position',[8.25*cubeSize+4*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,3,1},...
                  'visible','off');
buttons(23) = text('string',' \downarrow ',...
                  'position',[9.25*cubeSize+5*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,2,1},...
                  'visible','off');
buttons(24) = text('string',' \downarrow ',...
                  'position',[10.25*cubeSize+6*spaceSize -0.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,1,1},...
                  'visible','off');
buttons(25) = text('string',' \uparrow ',...
                  'position',[-3.5*cubeSize-2*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,2},...
                  'visible','off');
buttons(26) = text('string',' \uparrow ',...
                  'position',[-2.5*cubeSize-2*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,2},...
                  'visible','off');
buttons(27) = text('string',' \uparrow ',...
                  'position',[-1.5*cubeSize-2*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,2},...
                  'visible','off');
buttons(28) = text('string',' \uparrow ',...
                  'position',[8.25*cubeSize+4*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,3,2},...
                  'visible','off');
buttons(29) = text('string',' \uparrow ',...
                  'position',[9.25*cubeSize+5*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,2,2},...
                  'visible','off');
buttons(30) = text('string',' \uparrow ',...
                  'position',[10.25*cubeSize+6*spaceSize 3.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveY,1,2},...
                  'visible','off');
buttons(31) = text('string','\leftarrow',...
                  'position',[-0.5*cubeSize 4.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,1},...
                  'visible','off');
buttons(32) = text('string','\leftarrow',...
                  'position',[-0.5*cubeSize 5.5*cubeSize+3*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,1},...
                  'visible','off');
buttons(33) = text('string','\leftarrow',...
                  'position',[-0.5*cubeSize 6.5*cubeSize+4*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,1},...
                  'visible','off');
buttons(34) = text('string','\leftarrow',...
                  'position',[-0.5*cubeSize -1.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,2},...
                  'visible','off');
buttons(35) = text('string','\leftarrow',...
                  'position',[-0.5*cubeSize -2.5*cubeSize-1*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,2},...
                  'visible','off');
buttons(36) = text('string','\leftarrow',...
                  'position',[-0.5*cubeSize -3.5*cubeSize-2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,2},...
                  'visible','off');
buttons(37) = text('string','\rightarrow',...
                  'position',[3.25*cubeSize+2*spaceSize 4.5*cubeSize+2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,2},...
                  'visible','off');
buttons(38) = text('string','\rightarrow',...
                  'position',[3.25*cubeSize+2*spaceSize 5.5*cubeSize+3*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,2},...
                  'visible','off');
buttons(39) = text('string','\rightarrow',...
                  'position',[3.25*cubeSize+2*spaceSize 6.5*cubeSize+4*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,2},...
                  'visible','off');
buttons(40) = text('string','\rightarrow',...
                  'position',[3.25*cubeSize+2*spaceSize -1.5*cubeSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,1,1},...
                  'visible','off');
buttons(41) = text('string','\rightarrow',...
                  'position',[3.25*cubeSize+2*spaceSize -2.5*cubeSize-1*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,2,1},...
                  'visible','off');
buttons(42) = text('string','\rightarrow',...
                  'position',[3.25*cubeSize+2*spaceSize -3.5*cubeSize-2*spaceSize 10],...
                  'backgroundColor',[0.75 0.75 0.75],...
                  'buttondownfcn',{@moveZ,3,1},...
                  'visible','off');
setappdata(figH,'buttons',[buttons; axesH]);
buttondf = [get(buttons,'buttondownfcn'); {get(axesH,'buttondownfcn')}];
setappdata(figH,'buttondf',buttondf);
setappdata(figH,'redundant',buttons(19:42));

%menus
game = uimenu(figH,'label','Game');
uimenu(game,'label','New Game','Accelerator','n','callback',@scramble);
uimenu(game,'label','Solve','Accelerator','s','callback',@solve);
uimenu(game,'label','Quit','Accelerator','q','callback','delete(gcf)');
view = uimenu(figH,'label','View');
uimenu(view,'label','Colors','callback',{@colorPalette});
animation = uimenu(view,'label','Animation Speed');
speeds(1) = uimenu(animation,'label','Off','callback',{@changeSpeed,0},'Accelerator','0');
speeds(2) = uimenu(animation,'label','Slow','callback',{@changeSpeed,20},'Accelerator','1');
speeds(3) = uimenu(animation,'label','Medium','checked','on','callback',{@changeSpeed,10},'Accelerator','2');
speeds(4) = uimenu(animation,'label','Fast','callback',{@changeSpeed,5},'Accelerator','3');
setappdata(figH,'speeds',speeds);
uimenu(view,'label','3D View','checked','on','callback',@smallView);
uimenu(view,'label','Redundant Buttons','callback',@redundant);
help = uimenu(figH,'label','Help');
uimenu(help,'label','Help','callback',@menuHelp);
uimenu(help,'label','About','callback',@menuAbout);

%3D views
ah1 = axes('units','pixels','visible','off','projection','perspective',...
           'position',[border+12*cubeSize+6*spaceSize border 3*cubeSize+2*spaceSize 3*cubeSize+2*spaceSize],...
           'cameraposition', [6 6 6], 'cameratarget', [1.5 1.5 1.5], 'cameraupvector', [0 0 1]);
sph = zeros(15,12);
sph(7,1) = patch([3 3 3 3],[0 1 1 0],[0 0 1 1],[0 1 0]); %face 1
sph(7,2) = patch([3 3 3 3],[0 1 1 0],[1 1 2 2],[0 1 0]);
sph(7,3) = patch([3 3 3 3],[0 1 1 0],[2 2 3 3],[0 1 0]);
sph(8,1) = patch([3 3 3 3],[1 2 2 1],[0 0 1 1],[0 1 0]);
sph(8,2) = patch([3 3 3 3],[1 2 2 1],[1 1 2 2],[0 1 0]);
sph(8,3) = patch([3 3 3 3],[1 2 2 1],[2 2 3 3],[0 1 0]);
sph(9,1) = patch([3 3 3 3],[2 3 3 2],[0 0 1 1],[0 1 0]);
sph(9,2) = patch([3 3 3 3],[2 3 3 2],[1 1 2 2],[0 1 0]);
sph(9,3) = patch([3 3 3 3],[2 3 3 2],[2 2 3 3],[0 1 0]);
sph(12,4) = patch([3 2 2 3],[3 3 3 3],[0 0 1 1],[1 1 0]); %face 2
sph(11,4) = patch([3 2 2 3],[3 3 3 3],[1 1 2 2],[1 1 0]);
sph(10,4) = patch([3 2 2 3],[3 3 3 3],[2 2 3 3],[1 1 0]);
sph(12,5) = patch([2 1 1 2],[3 3 3 3],[0 0 1 1],[1 1 0]);
sph(11,5) = patch([2 1 1 2],[3 3 3 3],[1 1 2 2],[1 1 0]);
sph(10,5) = patch([2 1 1 2],[3 3 3 3],[2 2 3 3],[1 1 0]);
sph(12,6) = patch([1 0 0 1],[3 3 3 3],[0 0 1 1],[1 1 0]);
sph(11,6) = patch([1 0 0 1],[3 3 3 3],[1 1 2 2],[1 1 0]);
sph(10,6) = patch([1 0 0 1],[3 3 3 3],[2 2 3 3],[1 1 0]);
sph(7,4) = patch([3 2 2 3],[0 0 1 1],[3 3 3 3],[1 0 0]); %face 3
sph(8,4) = patch([3 2 2 3],[1 1 2 2],[3 3 3 3],[1 0 0]);
sph(9,4) = patch([3 2 2 3],[2 2 3 3],[3 3 3 3],[1 0 0]);
sph(7,5) = patch([2 1 1 2],[0 0 1 1],[3 3 3 3],[1 0 0]);
sph(8,5) = patch([2 1 1 2],[1 1 2 2],[3 3 3 3],[1 0 0]);
sph(9,5) = patch([2 1 1 2],[2 2 3 3],[3 3 3 3],[1 0 0]);
sph(7,6) = patch([1 0 0 1],[0 0 1 1],[3 3 3 3],[1 0 0]);
sph(8,6) = patch([1 0 0 1],[1 1 2 2],[3 3 3 3],[1 0 0]);
sph(9,6) = patch([1 0 0 1],[2 2 3 3],[3 3 3 3],[1 0 0]);
sph(7,12) = patch([3 2 2 3],[0 0 1 1],[0 0 0 0],[1 1 1]); %face 4
sph(8,12) = patch([3 2 2 3],[1 1 2 2],[0 0 0 0],[1 1 1]);
sph(9,12) = patch([3 2 2 3],[2 2 3 3],[0 0 0 0],[1 1 1]);
sph(7,11) = patch([2 1 1 2],[0 0 1 1],[0 0 0 0],[1 1 1]);
sph(8,11) = patch([2 1 1 2],[1 1 2 2],[0 0 0 0],[1 1 1]);
sph(9,11) = patch([2 1 1 2],[2 2 3 3],[0 0 0 0],[1 1 1]);
sph(7,10) = patch([1 0 0 1],[0 0 1 1],[0 0 0 0],[1 1 1]);
sph(8,10) = patch([1 0 0 1],[1 1 2 2],[0 0 0 0],[1 1 1]);
sph(9,10) = patch([1 0 0 1],[2 2 3 3],[0 0 0 0],[1 1 1]);
sph(4,4) = patch([3 2 2 3],[0 0 0 0],[0 0 1 1],[0 0 1]); %face 5
sph(5,4) = patch([3 2 2 3],[0 0 0 0],[1 1 2 2],[0 0 1]);
sph(6,4) = patch([3 2 2 3],[0 0 0 0],[2 2 3 3],[0 0 1]);
sph(4,5) = patch([2 1 1 2],[0 0 0 0],[0 0 1 1],[0 0 1]);
sph(5,5) = patch([2 1 1 2],[0 0 0 0],[1 1 2 2],[0 0 1]);
sph(6,5) = patch([2 1 1 2],[0 0 0 0],[2 2 3 3],[0 0 1]);
sph(4,6) = patch([1 0 0 1],[0 0 0 0],[0 0 1 1],[0 0 1]);
sph(5,6) = patch([1 0 0 1],[0 0 0 0],[1 1 2 2],[0 0 1]);
sph(6,6) = patch([1 0 0 1],[0 0 0 0],[2 2 3 3],[0 0 1]);
sph(7,9) = patch([0 0 0 0],[0 1 1 0],[0 0 1 1],[1 0.5 0]); %face 6
sph(7,8) = patch([0 0 0 0],[0 1 1 0],[1 1 2 2],[1 0.5 0]);
sph(7,7) = patch([0 0 0 0],[0 1 1 0],[2 2 3 3],[1 0.5 0]);
sph(8,9) = patch([0 0 0 0],[1 2 2 1],[0 0 1 1],[1 0.5 0]);
sph(8,8) = patch([0 0 0 0],[1 2 2 1],[1 1 2 2],[1 0.5 0]);
sph(8,7) = patch([0 0 0 0],[1 2 2 1],[2 2 3 3],[1 0.5 0]);
sph(9,9) = patch([0 0 0 0],[2 3 3 2],[0 0 1 1],[1 0.5 0]);
sph(9,8) = patch([0 0 0 0],[2 3 3 2],[1 1 2 2],[1 0.5 0]);
sph(9,7) = patch([0 0 0 0],[2 3 3 2],[2 2 3 3],[1 0.5 0]);
set(sph,'buttondownfcn',{@smallBDF})
setappdata(figH,'smallaxes',ah1);
setappdata(figH,'sph',sph);
set(ah1,'cameraviewanglemode','manual','cameraviewangle',45);
colorP = [0 1 0; ...
          1 1 0; ...
          1 0 0; ...
          1 1 1; ...
          0 0 1; ...
          1 0.5 0];
setappdata(figH,'colorP',colorP);
setappdata(figH,'scheme',2);

%custom pointer
point = [nan nan nan nan nan 1 1 1 1 nan nan nan nan nan nan nan; ...
         nan nan nan 1   1   1 1 2 2 1   1   1   nan nan nan nan; ...
         nan nan 1   2   2   2 1 2 2 1   2   2   1   1   nan nan; ...
         nan nan 1   2   2   2 1 2 2 1   2   2   1   2   1   nan; ...
         nan nan 1   1   2   2 2 2 2 1   2   2   1   2   2   1; ...
         1   1   nan 1   2   2 2 2 2 2   2   2   1   2   2   1; ...
         1   2   1   1   2   2 2 2 2 2   2   2   2   2   2   1; ...
         1   2   2   1   2   2 2 2 2 2   2   2   2   2   2   1; ...
         1   2   2   1   2   2 2 1 2 2   1   2   2   2   2   1; ...
         nan 1   2   2   2   2 2 1 2 2   1   2   2   2   2   1; ...
         nan 1   2   2   2   2 2 1 2 2   1   2   2   2   1   nan; ...
         nan nan 1   2   2   2 2 2 2 2   2   2   2   2   1   nan; ...
         nan nan 1   2   2   2 2 2 2 2   2   2   2   2   1   nan; ...
         nan nan nan 1   2   2 2 2 2 2   2   2   2   1   nan nan; ...
         nan nan nan nan 1   2 2 2 2 2   2   2   2   1   nan nan; ...
         nan nan nan nan 1   1 1 1 1 1   1   1   1   1   nan nan];
set(figH,'pointerShapeCData',point);


%scramble
scramble;

%------------------------------------------------------------------
function redundant(obj,eventData)

buttons = getappdata(gcf,'redundant');

check = get(gcbo,'checked');
switch check
    case 'on'
        set(gcbo,'checked','off');
        set(buttons,'visible','off');
    case 'off'
        set(gcbo,'checked','on');
        set(buttons,'visible','on');
end

%------------------------------------------------------------------
function smallBDF(obj,eventData)

set(gcf,'windowbuttonmotionfcn',{@windowBMF,get(gcbo,'parent')});
set(gcf,'windowbuttonupfcn',{@windowBUF});
setappdata(gcf,'lastpos',get(0,'pointerlocation'));
setappdata(gcf,'pointer',get(gcf,'pointer'));

%------------------------------------------------------------------
function windowBUF(obj,eventData)

set(gcf,'windowbuttonmotionfcn','');
set(gcf,'windowbuttonupfcn','');
set(gcf,'pointer',getappdata(gcf,'pointer'));

%------------------------------------------------------------------
function windowBMF(obj,eventData,aH)

lastpos = getappdata(gcf,'lastpos');
newpos = get(0,'pointerlocation');
setappdata(gcf,'lastpos',newpos);
set(gcf,'pointer','custom')

dtheta = lastpos(1)-newpos(1);
dphi = lastpos(2)-newpos(2);
camorbit(aH,dtheta,dphi,'camera');
set(aH,'XTick',[0 2 4],'YTick',[0 2 4],'ZTick',[0 2 4],...
       'XTickLabel',[0;2;4],'YTickLabel',[0;2;4],'ZTickLabel',[0;2;4],...
       'XLim',[0 4],'YLim',[0 4],'ZLim',[0 4]);
drawnow

%------------------------------------------------------------------
function smallView(obj,eventData)

checked = get(gcbo,'checked');
smallaxes = getappdata(gcf,'smallaxes');
child = get(smallaxes,'child');
switch checked
    case 'on'
        set(gcbo,'checked','off');
        set(child,'visible','off');
    case 'off'
        set(gcbo,'checked','on');
        set(child,'visible','on');
end

%------------------------------------------------------------------
function changeSpeed(obj,eventData,speed)

speeds = getappdata(gcf,'speeds');
for i1=1:length(speeds)
    set(speeds(i1),'checked','off');
end
set(gcbo,'checked','on');

setappdata(gcf,'animation',speed);

%------------------------------------------------------------------
function scramble(obj,eventData)

speed = getappdata(gcf,'animation');
setappdata(gcf,'animation',0);
fun = {@moveX,@moveY,@moveZ};

for i=1:50
    moves{i} = {fun{ceil(3*rand)},ceil(3*rand),ceil(2*rand)};
    feval(moves{i}{1},[],[],moves{i}{2},moves{i}{3});
end

setappdata(gcf,'animation',speed);

%------------------------------------------------------------------
function solve(obj,eventData)

%These solutions steps were put together and are copyrighted by Mark Jeays.
%This solution can be found at http://jeays.net/rubiks.htm

colors = getappdata(gcf,'colors');

%First Face
face = colors(8,5).face;
%edges
for i1=1:4
    oface = colors(11,5).face;
    [local,orient]=findPiece(face,oface);
    if local(3)==3
        if local(2)==1
            moveY([],[],1,2);          %L
            moveY([],[],1,2);          %L
            colors = moveZ([],[],3,1); %D
        elseif local(2)==3
            moveY([],[],3,1);          %R
            moveY([],[],3,1);          %R
            colors = moveZ([],[],3,2); %D'
        elseif local(1)==1
            moveX([],[],1,2);          %B'
            moveX([],[],1,2);          %B'
            moveZ([],[],3,1);          %D
            colors = moveZ([],[],3,1); %D
        elseif local(1)==3 & orient=='FU'
            moveX([],[],3,1);          %F'
            colors = moveX([],[],3,1); %F'
        end
    elseif local(3)==2
        if local(1:2)==[1 1]
            moveY([],[],1,1);          %L'
            moveZ([],[],3,1);          %D
            colors = moveY([],[],1,2); %L
        elseif local(1:2)==[1 3]
            moveY([],[],3,1);          %R
            moveZ([],[],3,2);          %D'
            colors = moveY([],[],3,2); %R'
        elseif local(1:2)==[3 1]
            moveY([],[],1,2);          %L
            moveZ([],[],3,1);          %D
            colors = moveY([],[],1,1); %L'
        elseif local(1:2)==[3 3]
            moveY([],[],3,2);          %R'
            moveZ([],[],3,2);          %D'
            colors = moveY([],[],3,1); %R
        end
    elseif local(3)==1
        if local(1)==1
            moveZ([],[],3,1);          %D
            colors = moveZ([],[],3,1); %D
        elseif local(2)==1
            colors = moveZ([],[],3,1); %D
        elseif local(2)==3
            colors = moveZ([],[],3,2); %D'
        end
    end
    [local,orient]=findPiece(face,oface);
    if local(3)~=3
        if orient=='DF'
            moveX([],[],3,2);        %F
            colors=moveX([],[],3,2); %F
        else
            moveZ([],[],3,1);        %D
            moveY([],[],3,1);        %R
            moveX([],[],3,1);        %F'
            colors=moveY([],[],3,2); %R'
        end
    end
    colors=orientIt([],[],13);
end
%corners
for i1=1:4
    oface1=colors(11,5).face;
    oface2=colors(8,8).face;
    [local,orient]=findPiece(face,oface1,oface2);
    if local(3)==3
        if local(1:2)==[1 1]
            moveY([],[],1,1);        %L'
            moveY([],[],3,2);        %R'
            moveZ([],[],3,1);        %D
            moveZ([],[],3,1);        %D
            moveY([],[],1,2);        %L
            colors=moveY([],[],3,1); %R
        elseif local(1:2)==[1 3]
            moveX([],[],3,2);        %F
            moveX([],[],1,2);        %B'
            moveZ([],[],3,2);        %D'
            moveX([],[],3,1);        %F'
            colors=moveX([],[],1,1); %B
        elseif local(1:2)==[3 1]
            moveY([],[],1,2);        %L
            moveY([],[],3,2);        %R'
            moveZ([],[],3,1);        %D
            moveY([],[],1,1);        %L'
            colors=moveY([],[],3,1); %R
        end
    elseif local(3)==1
        if local(1:2)==[1 1]
            moveY([],[],3,2);        %R'
            moveZ([],[],3,1);        %D
            moveZ([],[],3,1);        %D
            colors=moveY([],[],3,1); %R
        elseif local(1:2)==[1 3]
            moveZ([],[],3,2);        %D'
            moveY([],[],3,2);        %R'
            moveZ([],[],3,2);        %D'
            colors=moveY([],[],3,1); %R
        elseif local(1:2)==[3 1]
            moveY([],[],3,2);        %R'
            moveZ([],[],3,1);        %D
            colors=moveY([],[],3,1); %R
        elseif local(1:2)==[3 3]
            moveY([],[],3,2);        %R'
            moveZ([],[],3,2);        %D'
            colors=moveY([],[],3,1); %R
        end
    end
    [local,orient]=findPiece(face,oface1,oface2);
    if orient=='FRU'
        colors=rotateCorner('cWise');
    elseif orient=='RUF'
        colors=rotateCorner('ccWise');
    end
    colors=orientIt([],[],13);
end

%middle edges
for i1=1:4
    face=colors(11,5).face;
    oface=colors(8,8).face;
    [local,orient]=findPiece(face,oface);
    if ~all(local==[3 3 2]) | ~all(orient=='FR')
        if local==[1 1 2]
            moveZ([],[],2,1);
            moveZ([],[],2,1);
            placeEdge('right');
            moveZ([],[],2,1);
            colors = moveZ([],[],2,1);
        elseif local==[3 1 2]
            moveZ([],[],2,1);
            placeEdge('right');
            colors = moveZ([],[],2,2);
        elseif local==[1 3 2]
            moveZ([],[],2,2);
            placeEdge('right');
            colors = moveZ([],[],2,1);
        elseif local==[3 3 2]
            colors = placeEdge('right');
        end
        [local,orient]=findPiece(face,oface);
        if orient(1)=='D'
            dir='right';
            if local(1)==3
                moveZ([],[],3,1);        %D
                colors=moveZ([],[],3,1); %D
            elseif local(2)==1
                colors=moveZ([],[],3,2); %D'
            elseif local(2)==3
                colors=moveZ([],[],3,1); %D
            end
        elseif orient(2)=='D'
            dir='left';
            if local(1)==1
                colors=moveZ([],[],3,1); %D
            elseif local(1)==3
                colors=moveZ([],[],3,2); %D'
            elseif local(2)==3
                moveZ([],[],3,1);        %D
                colors=moveZ([],[],3,1); %D
            end
        else
            error('something''s wrong')
        end
        placeEdge(dir);
    end
    colors=orientIt([],[],13);
end

%flip It
orientIt([],[],11);
colors = orientIt([],[],11);

%form cross
face = colors(8,5).face;
cross(1) = (colors(7,5).face==face);
cross(2) = (colors(8,4).face==face);
cross(3) = (colors(9,5).face==face);
cross(4) = (colors(8,6).face==face);
if (all(cross([1 3])) | all(cross([2 4]))) & sum(cross)==2
    if all(cross([1 3]))
        colors=orientIt([],[],13);
    end
    moveX([],[],1,1);        %B
    moveY([],[],1,2);        %L
    moveZ([],[],1,2);        %U
    moveY([],[],1,1);        %L'
    moveZ([],[],1,1);        %U'
    colors=moveX([],[],1,2); %B'
elseif ~sum(cross)
    moveX([],[],1,1);        %B
    moveY([],[],1,2);        %L
    moveZ([],[],1,2);        %U
    moveY([],[],1,1);        %L'
    moveZ([],[],1,1);        %U'
    moveX([],[],1,2);        %B'
    moveX([],[],3,2);        %F
    moveZ([],[],1,2);        %U
    moveY([],[],3,1);        %R
    moveZ([],[],1,1);        %U'
    moveY([],[],3,2);        %R'
    colors=moveX([],[],3,1); %F'
elseif sum(cross)<4
    if all(cross(1:2))
        orientIt([],[],13);
        colors=orientIt([],[],13);
    elseif all(cross(2:3))
        colors=orientIt([],[],13);
    elseif all(cross([1 4]))
        colors=orientIt([],[],13);
        orientIt([],[],13);
        colors=orientIt([],[],13);
    end
    moveX([],[],1,1);        %B
    moveZ([],[],1,2);        %U
    moveY([],[],1,2);        %L
    moveZ([],[],1,1);        %U'
    moveY([],[],1,1);        %L'
    colors=moveX([],[],1,2); %B'
end

if any(face~=[colors(7,5).face colors(9,5).face colors(8,4).face colors(8,6).face]);
    keyboard
end

%orient cross
cross(1) = (colors(6,5).face==colors(5,5).face);
cross(2) = (colors(8,3).face==colors(8,2).face);
cross(3) = (colors(10,5).face==colors(11,5).face);
cross(4) = (colors(8,7).face==colors(8,8).face);
if ~sum(cross)
    colors=moveZ([],[],1,2);
    if colors(6,5).face~=colors(5,5).face
        colors=moveZ([],[],1,2);
    end
    if colors(6,5).face~=colors(5,5).face
        colors=moveZ([],[],1,2);
    end
    cross(1) = (colors(6,5).face==colors(5,5).face);
    cross(2) = (colors(8,3).face==colors(8,2).face);
    cross(3) = (colors(10,5).face==colors(11,5).face);
    cross(4) = (colors(8,7).face==colors(8,8).face);
end
if (all(cross([1 3])) | all(cross([2 4]))) & sum(cross)==2
    [local]=findPiece(face,colors(8,8).face);
    if local(1)==1
        moveZ([],[],1,2); %U
        moveZ([],[],1,2); %U
    elseif local(2)==1
        moveZ([],[],1,1); %U'
    elseif local(2)==3
        moveZ([],[],1,2); %U
    end
    moveY([],[],3,1);        %R
    moveY([],[],3,1);        %R
    moveZ([],[],3,1);        %D
    moveZ([],[],3,1);        %D
    moveX([],[],1,1);        %B
    moveX([],[],1,1);        %B
    moveZ([],[],3,1);        %D
    moveY([],[],1,2);        %L
    moveY([],[],1,2);        %L
    moveX([],[],3,2);        %F
    moveX([],[],3,2);        %F
    moveY([],[],1,2);        %L
    moveY([],[],1,2);        %L
    moveX([],[],3,2);        %F
    moveX([],[],3,2);        %F
    moveY([],[],1,2);        %L
    moveY([],[],1,2);        %L
    moveX([],[],3,2);        %F
    moveX([],[],3,2);        %F
    moveZ([],[],3,2);        %D'
    moveX([],[],1,1);        %B
    moveX([],[],1,1);        %B
    moveZ([],[],3,1);        %D
    moveZ([],[],3,1);        %D
    moveY([],[],3,1);        %R
    colors=moveY([],[],3,1); %R
elseif sum(cross)<4
    if sum(cross)>1
        colors=moveZ([],[],1,2); %U
        cross(1) = (colors(6,5).face==colors(5,5).face);
        cross(2) = (colors(8,3).face==colors(8,2).face);
        cross(3) = (colors(10,5).face==colors(11,5).face);
        cross(4) = (colors(8,7).face==colors(8,8).face);
    end
    if cross(1)
        colors=orientIt([],[],13);
    elseif cross(3)
        orientIt([],[],13);
        orientIt([],[],13);
        colors=orientIt([],[],13);
    elseif cross(4)
        orientIt([],[],13);
        colors=orientIt([],[],13);
    end
    if colors(6,5).face==colors(11,5).face
        moveY([],[],3,1);        %R
        moveY([],[],3,1);        %R
        moveZ([],[],3,2);        %D'
        moveY([],[],3,2);        %R'
        moveY([],[],1,2);        %L
        moveX([],[],3,2);        %F
        moveX([],[],3,2);        %F
        moveY([],[],3,1);        %R
        moveY([],[],1,1);        %L'
        moveZ([],[],1,2);        %U
        moveZ([],[],1,2);        %U
        moveZ([],[],3,1);        %D
        moveY([],[],3,1);        %R
        colors=moveY([],[],3,1); %R
    else
        moveY([],[],3,1);        %R
        moveY([],[],3,1);        %R
        moveZ([],[],3,2);        %D'
        moveZ([],[],1,2);        %U
        moveZ([],[],1,2);        %U
        moveY([],[],3,2);        %R'
        moveY([],[],1,2);        %L
        moveX([],[],3,2);        %F
        moveX([],[],3,2);        %F
        moveY([],[],3,1);        %R
        moveY([],[],1,1);        %L'
        moveZ([],[],3,1);        %D
        moveY([],[],3,1);        %R
        colors=moveY([],[],3,1); %R
    end
end

%position corners
cross = [];
face1 = colors(5,5).face;
face2 = colors(8,2).face;
face3 = colors(11,5).face;
face4 = colors(8,8).face;
[local] = findPiece(face,face1,face2);
if local(1:2)==[1 1]
    cross(1)=1;
elseif local(1:2)==[3 1]
    cross(2)=1;
elseif local(1:2)==[1 3]
    cross(4)=1;
else
    cross(3)=1;
end
[local] = findPiece(face,face2,face3);
if local(1:2)==[1 1]
    cross(1)=2;
elseif local(1:2)==[3 1]
    cross(2)=2;
elseif local(1:2)==[1 3]
    cross(4)=2;
else
    cross(3)=2;
end
[local] = findPiece(face,face3,face4);
if local(1:2)==[1 1]
    cross(1)=3;
elseif local(1:2)==[3 1]
    cross(2)=3;
elseif local(1:2)==[1 3]
    cross(4)=3;
else
    cross(3)=3;
end
[local] = findPiece(face,face4,face1);
if local(1:2)==[1 1]
    cross(1)=4;
elseif local(1:2)==[3 1]
    cross(2)=4;
elseif local(1:2)==[1 3]
    cross(4)=4;
else
    cross(3)=4;
end
if ~all(cross==[1:4])
    if sum(cross==[1:4])==1
        if cross(1)==1
            if cross(2)==3
                dir = 'ccWise';
            else
                dir = 'cWise';
            end
            orientIt([],[],13);
            orientIt([],[],13);
        elseif cross(2)==2
            if cross(3)==4
                dir = 'ccWise';
            else
                dir = 'cWise';
            end
            orientIt([],[],13);
        elseif cross(3)==3
            if cross(4)==1
                dir = 'ccWise';
            else
                dir = 'cWise';
            end
        elseif cross(4)==4
            if cross(1)==2
                dir = 'ccWise';
            else
                dir = 'cWise';
            end
            orientIt([],[],13);
            orientIt([],[],13);
            orientIt([],[],13);
        end
        switch dir
            case 'ccWise'
                moveZ([],[],1,2);        %U
                moveY([],[],3,1);        %R
                moveZ([],[],1,1);        %U'
                moveY([],[],1,1);        %L'
                moveZ([],[],1,2);        %U
                moveY([],[],3,2);        %R'
                moveZ([],[],1,1);        %U'
                colors=moveY([],[],1,2); %L
            case 'cWise'
                moveY([],[],1,1);        %L'
                moveZ([],[],1,2);        %U
                moveY([],[],3,1);        %R
                moveZ([],[],1,1);        %U'
                moveY([],[],1,2);        %L
                moveZ([],[],1,2);        %U
                moveY([],[],3,2);        %R'
                colors=moveZ([],[],1,1); %U'
        end
    elseif cross(1)==3
        moveY([],[],3,2);        %R'
        moveX([],[],1,1);        %B
        moveX([],[],1,1);        %B
        moveX([],[],3,2);        %F
        moveY([],[],3,1);        %R
        moveX([],[],3,1);        %F'
        moveY([],[],3,2);        %R'
        moveX([],[],3,2);        %F
        moveY([],[],3,1);        %R
        moveX([],[],3,1);        %F'
        moveY([],[],3,2);        %R'
        moveX([],[],3,2);        %F
        moveY([],[],3,1);        %R
        moveX([],[],3,1);        %F'
        moveY([],[],3,2);        %R'
        moveX([],[],1,1);        %B
        moveX([],[],1,1);        %B
        colors=moveY([],[],3,1); %R
    else
        if cross(1)==2
            orientIt([],[],13);
        end
        moveX([],[],1,1);        %B
        moveY([],[],1,2);        %L
        moveZ([],[],1,2);        %U
        moveY([],[],1,1);        %L'
        moveZ([],[],1,1);        %U'
        moveY([],[],1,2);        %L
        moveZ([],[],1,2);        %U
        moveY([],[],1,1);        %L'
        moveZ([],[],1,1);        %U'
        moveY([],[],1,2);        %L
        moveZ([],[],1,2);        %U
        moveY([],[],1,1);        %L'
        moveZ([],[],1,1);        %U'
        colors=moveX([],[],1,2); %B'
    end
end

%orient corners
for i1=1:4
    face3 = colors(11,5).face;
    face4 = colors(8,8).face;
    [local,orient]=findPiece(face,face3,face4);
    if orient=='FRU'
        rotateCorner('cWise');
        moveZ([],[],1,1); %U'
        rotateCorner('cWise');
        rotateCorner('cWise');
        moveZ([],[],2,1);
        colors=moveZ([],[],3,1); %U'
    elseif orient=='RUF'
        rotateCorner('ccWise');
        moveZ([],[],1,1); %U'
        rotateCorner('ccWise');
        rotateCorner('ccWise');
        moveZ([],[],2,1);
        colors=moveZ([],[],3,1); %D
    else
        colors=orientIt([],[],13);
    end
end


%-----------------------------------------------------------------
function colors=placeEdge(direction)

switch direction
    case 'right'
        moveX([],[],3,2);          %F
        moveZ([],[],3,1);          %D
        moveX([],[],3,1);          %F'
        moveZ([],[],3,2);          %D'
        moveY([],[],3,2);          %R'
        moveZ([],[],3,2);          %D'
        colors = moveY([],[],3,1); %R
    case 'left'
        moveY([],[],3,2);          %R'
        moveZ([],[],3,2);          %D' 
        moveY([],[],3,1);          %R
        moveZ([],[],3,1);          %D  
        moveX([],[],3,2);          %F
        moveZ([],[],3,1);          %D  
        colors = moveX([],[],3,1); %F'
    otherwise
        error('wrong direction')
end

%-----------------------------------------------------------------
function colors=rotateCorner(direction)

switch direction
    case 'cWise'
        moveX([],[],3,2);        %F
        moveZ([],[],3,1);        %D
        moveX([],[],3,1);        %F'
        moveZ([],[],3,2);        %D'
        moveX([],[],3,2);        %F
        moveZ([],[],3,1);        %D
        moveX([],[],3,1);        %F'
        colors=moveZ([],[],3,2); %D'
    case 'ccWise'
        moveY([],[],3,2);        %R'
        moveZ([],[],3,2);        %D'
        moveY([],[],3,1);        %R
        moveZ([],[],3,1);        %D
        moveY([],[],3,2);        %R'
        moveZ([],[],3,2);        %D'
        moveY([],[],3,1);        %R
        colors=moveZ([],[],3,1); %D
end
        

%------------------------------------------------------------------
function [local,orient] = findPiece(face1,face2,face3)

colors=getappdata(gcf,'colors');

switch nargin
    case 2
        if colors(6,5).face==face1 & colors(7,5).face==face2
            local=[1 2 3];
            orient='BU';
        elseif colors(8,3).face==face1 & colors(8,4).face==face2
            local=[2 1 3];
            orient='LU';
        elseif colors(8,6).face==face1 & colors(8,7).face==face2
            local=[2 3 3];
            orient='UR';
        elseif colors(9,5).face==face1 & colors(10,5).face==face2
            local=[3 2 3];
            orient='UF';
        elseif colors(5,4).face==face1 & colors(7,2).face==face2
            local=[1 1 2];
            orient='BL';
        elseif colors(5,6).face==face1 & colors(7,8).face==face2
            local=[1 3 2];
            orient='BR';
        elseif colors(9,2).face==face1 & colors(11,4).face==face2
            local=[3 1 2];
            orient='LF';
        elseif colors(9,8).face==face1 & colors(11,6).face==face2
            local=[3 3 2];
            orient='RF';
        elseif colors(4,5).face==face1 & colors(7,11).face==face2
            local=[1 2 1];
            orient='BD';
        elseif colors(8,1).face==face1 & colors(8,12).face==face2
            local=[2 1 1];
            orient='LD';
        elseif colors(8,9).face==face1 & colors(8,10).face==face2
            local=[2 3 1];
            orient='RD';
        elseif colors(12,5).face==face1 & colors(9,11).face==face2
            local=[3 2 1];
            orient='FD';
        elseif colors(6,5).face==face2 & colors(7,5).face==face1
            local=[1 2 3];
            orient='UB';
        elseif colors(8,3).face==face2 & colors(8,4).face==face1
            local=[2 1 3];
            orient='UL';
        elseif colors(8,6).face==face2 & colors(8,7).face==face1
            local=[2 3 3];
            orient='RU';
        elseif colors(9,5).face==face2 & colors(10,5).face==face1
            local=[3 2 3];
            orient='FU';
        elseif colors(5,4).face==face2 & colors(7,2).face==face1
            local=[1 1 2];
            orient='LB';
        elseif colors(5,6).face==face2 & colors(7,8).face==face1
            local=[1 3 2];
            orient='RB';
        elseif colors(9,2).face==face2 & colors(11,4).face==face1
            local=[3 1 2];
            orient='FL';
        elseif colors(9,8).face==face2 & colors(11,6).face==face1
            local=[3 3 2];
            orient='FR';
        elseif colors(4,5).face==face2 & colors(7,11).face==face1
            local=[1 2 1];
            orient='DB';
        elseif colors(8,1).face==face2 & colors(8,12).face==face1
            local=[2 1 1];
            orient='DL';
        elseif colors(8,9).face==face2 & colors(8,10).face==face1
            local=[2 3 1];
            orient='DR';
        elseif colors(12,5).face==face2 & colors(9,11).face==face1
            local=[3 2 1];
            orient='DF';
        else
            error(sprintf('Could not find subcube with face1:%d and face2:%d',face1,face2));
        end
    case 3
        if colors(6,4).face==face1 & colors(7,3).face==face2 & colors(7,4).face==face3
            local=[1 1 3];
            orient='BLU';
        elseif colors(6,6).face==face1 & colors(7,6).face==face2 & colors(7,7).face==face3
            local=[1 3 3];
            orient='BUR';
        elseif colors(9,3).face==face1 & colors(10,4).face==face2 & colors(9,4).face==face3
            local=[3 1 3];
            orient='LFU';
        elseif colors(9,6).face==face1 & colors(10,6).face==face2 & colors(9,7).face==face3
            local=[3 3 3];
            orient='UFR';
        elseif colors(7,1).face==face1 & colors(4,4).face==face2 & colors(7,12).face==face3
            local=[1 1 1];
            orient='LDB';
        elseif colors(4,6).face==face1 & colors(7,9).face==face2 & colors(7,10).face==face3
            local=[1 3 1];
            orient='BRD';
        elseif colors(12,4).face==face1 & colors(9,1).face==face2 & colors(9,12).face==face3
            local=[3 1 1];
            orient='FLD';
        elseif colors(12,6).face==face1 & colors(9,10).face==face2 & colors(9,9).face==face3
            local=[3 3 1];
            orient='FDR';
        elseif colors(6,4).face==face2 & colors(7,3).face==face3 & colors(7,4).face==face1
            local=[1 1 3];
            orient='UBL';
        elseif colors(6,6).face==face2 & colors(7,6).face==face3 & colors(7,7).face==face1
            local=[1 3 3];
            orient='RBU';
        elseif colors(9,3).face==face2 & colors(10,4).face==face3 & colors(9,4).face==face1
            local=[3 1 3];
            orient='ULF';
        elseif colors(9,6).face==face2 & colors(10,6).face==face3 & colors(9,7).face==face1
            local=[3 3 3];
            orient='RUF';
        elseif colors(7,1).face==face2 & colors(4,4).face==face3 & colors(7,12).face==face1
            local=[1 1 1];
            orient='BLD';
        elseif colors(4,6).face==face2 & colors(7,9).face==face3 & colors(7,10).face==face1
            local=[1 3 1];
            orient='DBR';
        elseif colors(12,4).face==face2 & colors(9,1).face==face3 & colors(9,12).face==face1
            local=[3 1 1];
            orient='DFL';
        elseif colors(12,6).face==face2 & colors(9,10).face==face3 & colors(9,9).face==face1
            local=[3 3 1];
            orient='RFD';
        elseif colors(6,4).face==face3 & colors(7,3).face==face1 & colors(7,4).face==face2
            local=[1 1 3];
            orient='LUB';
        elseif colors(6,6).face==face3 & colors(7,6).face==face1 & colors(7,7).face==face2
            local=[1 3 3];
            orient='URB';
        elseif colors(9,3).face==face3 & colors(10,4).face==face1 & colors(9,4).face==face2
            local=[3 1 3];
            orient='FUL';
        elseif colors(9,6).face==face3 & colors(10,6).face==face1 & colors(9,7).face==face2
            local=[3 3 3];
            orient='FRU';
        elseif colors(7,1).face==face3 & colors(4,4).face==face1 & colors(7,12).face==face2
            local=[1 1 1];
            orient='DBL';
        elseif colors(4,6).face==face3 & colors(7,9).face==face1 & colors(7,10).face==face2
            local=[1 3 1];
            orient='RDB';
        elseif colors(12,4).face==face3 & colors(9,1).face==face1 & colors(9,12).face==face2
            local=[3 1 1];
            orient='LDF';
        elseif colors(12,6).face==face3 & colors(9,10).face==face1 & colors(9,9).face==face2
            local=[3 3 1];
            orient='DRF';
        else
            error(sprintf('Could not find subcube with face1:%d, face2:%d, and face3:%d',face1,face2,face3));
        end
    case 1
        if colors(5,5).face==face1
            local=[1 2 2];
            orient='B';
        elseif colors(8,2).face==face1
            local=[2 1 2];
            orient='L';
        elseif colors(8,5).face==face1
            local=[2 2 3];
            orient='U';
        elseif colors(8,8).face==face1
            local=[2 3 2];
            orient='R';
        elseif colors(8,11).face==face1
            local=[2 2 1];
            orient='D';
        elseif colors(11,5).face==face1
            local=[3 2 2];
            orient='F';
        else
            error(sprintf('Could not find subcube with face1:%d',face1));
        end
    otherwise
        error('Incorrect number of inputs.')
end

%-----------------------------------------------------------------
function p = buildPatch(pt,cubeSize,spaceSize,color);
p(1,1) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)],...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize]+2*cubeSize+2*spaceSize,color);
p(1,2) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)]+cubeSize+spaceSize,...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize]+2*cubeSize+2*spaceSize,color);
p(1,3) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)]+2*cubeSize+2*spaceSize,...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize]+2*cubeSize+2*spaceSize,color);
p(2,1) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)],...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize]+cubeSize+spaceSize,color);
p(2,2) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)]+cubeSize+spaceSize,...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize]+cubeSize+spaceSize,color);
p(2,3) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)]+2*cubeSize+2*spaceSize,...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize]+cubeSize+spaceSize,color);
p(3,1) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)],...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize],color);
p(3,2) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)]+cubeSize+spaceSize,...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize],color);
p(3,3) = patch([pt(1) pt(1)+cubeSize pt(1)+cubeSize pt(1)]+2*cubeSize+2*spaceSize,...
               [pt(2) pt(2) pt(2)+cubeSize pt(2)+cubeSize],color);

%--------------------------------------------------------------------
function changeColor(hanGrey,hanCol)

if ischar(hanCol)
    for i1=1:length(hanGrey)
        set(hanGrey(i1),'faceColor',[0.5 0.5 0.5]);
    end
else
    for i1=1:length(hanGrey)
        set(hanGrey(i1),'faceColor',get(hanCol(i1),'faceColor'));
    end
end

%--------------------------------------------------------------------
function reColor(ph,colors)

sph = getappdata(gcf,'sph');
for i1=1:prod(size(ph))
    set(ph(i1),'faceColor',colors(i1).color)
    if ~all(colors(i1).color==[0.5 0.5 0.5])
      set(sph(i1),'faceColor',colors(i1).color)
    end
end

%--------------------------------------------------------------------
function animation(right,left,up,down,cWise,ccWise)

cubeSize = getappdata(gcf,'cubeSize');
spaceSize = getappdata(gcf,'spaceSize');
numSteps = getappdata(gcf,'animation');

distance = 4*cubeSize+2*spaceSize;
del = distance/numSteps;
alpha = 90/numSteps;

for i1=1:numSteps
    for i2=1:prod(size(right))
        moveGen(right(i2),'horz',del);
    end
    for i2=1:prod(size(left))
        moveGen(left(i2),'horz',-del);
    end
    for i2=1:prod(size(up))
        moveGen(up(i2),'vert',del);
    end
    for i2=1:prod(size(down))
        moveGen(down(i2),'vert',-del);
    end
    if ~isempty(cWise)
        moveGen(cWise,'rotate',-alpha,cWise(2,2));
    end
    if ~isempty(ccWise)
        moveGen(ccWise,'rotate',alpha,ccWise(2,2));
    end
    drawnow
end
for i2=1:prod(size(right))
    moveGen(right(i2),'horz',-distance);
end
for i2=1:prod(size(left))
    moveGen(left(i2),'horz',distance);
end
for i2=1:prod(size(up))
    moveGen(up(i2),'vert',-distance);
end
for i2=1:prod(size(down))
    moveGen(down(i2),'vert',distance);
end
if ~isempty(cWise)
    moveGen(cWise,'rotate',90,cWise(2,2));
end
if ~isempty(ccWise)
    moveGen(ccWise,'rotate',-90,ccWise(2,2));
end

%--------------------------------------------------------------------
function moveGen(hans,dir,del,center)

switch dir
    case 'horz'
        xdata = get(hans,'xdata');
        set(hans,'xdata',xdata+del);
    case 'vert'
        ydata = get(hans,'ydata');
        set(hans,'ydata',ydata+del);
    case 'rotate'
        xc = mean(get(center,'xdata'));
        yc = mean(get(center,'ydata'));
        rotate(hans,[0 0 1],del,[xc,yc,0]);
end

%--------------------------------------------------------------------
function switchCallBack(action)

buttons = getappdata(gcf,'buttons');
ph = getappdata(gcf,'ph');

switch action
    case 'off'
        for i1=1:length(buttons)
            set(buttons(i1),'buttondownfcn','');
        end
        for i1=1:prod(size(ph))
            set(ph(i1),'buttondownfcn','');
        end
        set(gcf,'pointer','watch');
    case 'on'
        buttondf = getappdata(gcf,'buttondf');
        for i1=1:length(buttons)
            set(buttons(i1),'buttondownfcn',buttondf{i1});
        end
        phbuttondf = getappdata(gcf,'phbuttondf');
        for i1=1:prod(size(ph))
            set(ph(i1),'buttondownfcn',phbuttondf{i1});
        end
        set(gcf,'pointer','arrow');
end

%--------------------------------------------------------------------
function colors = moveX(obj,eventData,num,dir)

switchCallBack('off');
ph = getappdata(gcf,'ph');
sph = getappdata(gcf,'sph');
colors = getappdata(gcf,'colors');

right = [];
left = [];
up = [];
down = [];
cWise = [];
ccWise = [];

if any(num==1)
    
    switch dir
        case 2
            changeColor(ph(13,10:12),ph(7,10:12));
            right = [right ph(13,10:12) ph(7,1:12)];
            ccWise = [ccWise ph(4:6,4:6)];
            colors(7,1:12) = [colors(7,10:12) colors(7,1:9)];
            colors(4:6,4:6) = colors(4:6,[6 5 4])';
        case 1
            changeColor(ph(1,10:12),ph(7,1:3));
            left = [left ph(1,10:12) ph(7,1:12)];
            cWise = [cWise ph(4:6,4:6)];
            colors(7,1:12) = [colors(7,4:12) colors(7,1:3)];
            colors(4:6,4:6) = colors([6 5 4],4:6)';
    end
end
if any(num==3)
    switch dir
        case 2
            changeColor(ph(15,10:12),ph(9,10:12));
            right = [right ph(15,10:12) ph(9,1:12)];
            cWise = [cWise ph(10:12,4:6)];
            colors(9,1:12) = [colors(9,10:12) colors(9,1:9)];
            colors(10:12,4:6) = colors([12 11 10],4:6)';
        case 1
            changeColor(ph(3,10:12),ph(9,1:3));
            left = [left ph(3,10:12) ph(9,1:12)];
            ccWise = [ccWise ph(10:12,4:6)];
            colors(9,1:12) = [colors(9,4:12) colors(9,1:3)];
            colors(10:12,4:6) = colors(10:12,[6 5 4])';
    end
end
if any(num==2)
    switch dir
        case 2
            changeColor(ph(14,10:12),ph(8,10:12));
            right = [right ph(14,10:12) ph(8,1:12)];
            colors(8,1:12) = [colors(8,10:12) colors(8,1:9)];
        case 1
            changeColor(ph(2,10:12),ph(8,1:3));
            left = [left ph(2,10:12) ph(8,1:12)];
            colors(8,1:12) = [colors(8,4:12) colors(8,1:3)];
    end
end

setappdata(gcf,'colors',colors);
if getappdata(gcf,'animation')
    animation(right,left,up,down,cWise,ccWise);
end
reColor(ph,colors);
switchCallBack('on');

%--------------------------------------------------------------------
function colors = moveY(obj,eventData,num,dir)

switchCallBack('off');
ph = getappdata(gcf,'ph');
colors = getappdata(gcf,'colors');

right = [];
left = [];
up = [];
down = [];
cWise = [];
ccWise = [];


if any(num==1)
    switch dir
        case 1
            changeColor(ph(13:15,4),ph([9 8 7],12));
            changeColor(ph(4:6,12),ph([6 5 4],4));
            up = [up; ph(4:15,4)];
            down = [down ph(4:9,12)];
            ccWise = [ccWise ph(7:9,1:3)];
            tmp = colors([6 5 4],4);
            colors(4:12,4) = [colors(7:12,4); colors([9 8 7],12)];
            colors(7:9,12) = tmp;
            colors(7:9,1:3) = colors(7:9,[3 2 1])';
        case 2
            changeColor(ph(1:3,4),ph([9 8 7],12));
            changeColor(ph(10:12,12),ph([12 11 10],4));
            down = [down; ph(1:12,4)];
            up = [up; ph(7:12,12)];
            cWise = [cWise ph(7:9,1:3)];
            tmp = colors([12 11 10],4);
            colors(4:12,4) = [colors([9 8 7],12); colors(4:9,4)];
            colors(7:9,12) = tmp;
            colors(7:9,1:3) = colors([9 8 7],1:3)';
    end
end
if any(num==3)
    switch dir
        case 1
            changeColor(ph(13:15,6),ph([9 8 7],10));
            changeColor(ph(4:6,10),ph([6 5 4],6));
            up = [up; ph(4:15,6)];
            down = [down; ph(4:9,10)];
            cWise = [cWise ph(7:9,7:9)];
            tmp = colors([6 5 4],6);
            colors(4:12,6) = [colors(7:12,6); colors([9 8 7],10)];
            colors(7:9,10) = tmp;
            colors(7:9,7:9) = colors([9 8 7],7:9)';
        case 2
            changeColor(ph(1:3,6),ph([9 8 7],10));
            changeColor(ph(10:12,10),ph([12 11 10],6));
            down = [down; ph(1:12,6)];
            up = [up; ph(7:12,10)];
            ccWise = [ccWise ph(7:9,7:9)];
            tmp = colors([12 11 10],6);
            colors(4:12,6) = [colors([9 8 7],10); colors(4:9,6)];
            colors(7:9,10) = tmp;
            colors(7:9,7:9) = colors(7:9,[9 8 7])';
    end
end
if any(num==2)
    switch dir
        case 1
            changeColor(ph(13:15,5),ph([9 8 7],11));
            changeColor(ph(4:6,11),ph([6 5 4],5));
            up = [up; ph(4:15,5)];
            down = [down; ph(4:9,11)];
            tmp = colors([6 5 4],5);
            colors(4:12,5) = [colors(7:12,5); colors([9 8 7],11)];
            colors(7:9,11) = tmp;
        case 2
            changeColor(ph(1:3,5),ph([9 8 7],11));
            changeColor(ph(10:12,11),ph([12 11 10],5));
            down = [down; ph(1:12,5)];
            up = [up; ph(7:12,11)];
            tmp = colors([12 11 10],5);
            colors(4:12,5) = [colors([9 8 7],11); colors(4:9,5)];
            colors(7:9,11) = tmp;
    end
end

setappdata(gcf,'colors',colors);
if getappdata(gcf,'animation')
    animation(right,left,up,down,cWise,ccWise);
end
reColor(ph,colors);
switchCallBack('on');


%--------------------------------------------------------------------
function colors = moveZ(obj,eventData,num,dir)

switchCallBack('off');
ph = getappdata(gcf,'ph');
colors = getappdata(gcf,'colors');

right = [];
left = [];
up = [];
down = [];
cWise = [];
ccWise = [];

if any(num==1)
    switch dir
        case 1
            changeColor(ph(13:15,7),ph(10,[6 5 4]));
            changeColor(ph(10,1:3),ph(7:9,3));
            changeColor(ph(1:3,3),ph(6,[6 5 4]));
            changeColor(ph(6,7:9),ph(7:9,7));
            up = [up; ph(7:9,7) ph(13:15,7)];
            down = [down; ph(1:3,3) ph(7:9,3)];
            right = [right ph(10,1:6)];
            left = [left ph(6,4:9)];
            ccWise = [ccWise ph(7:9,4:6)];
            tmp = colors(10,[6 5 4]);
            colors(10,4:6) = colors(7:9,3);
            colors(7:9,3) = colors(6,[6 5 4]);
            colors(6,4:6) = colors(7:9,7);
            colors(7:9,7) = tmp;
            colors(7:9,4:6) = colors(7:9,[6 5 4])';
        case 2
            changeColor(ph(10,7:9),ph([9 8 7],7));
            changeColor(ph(1:3,7),ph(6,4:6));
            changeColor(ph(6,1:3),ph([9 8 7],3));
            changeColor(ph(13:15,3),ph(10,4:6));
            up = [up; ph(13:15,3) ph(7:9,3)];
            down = [down; ph(1:3,7) ph(7:9,7)];
            right = [right ph(6,1:6)];
            left = [left ph(10,4:9)];
            cWise = [cWise ph(7:9,4:6)];
            tmp = colors(6,4:6);
            colors(6,4:6) = colors([9 8 7],3);
            colors(7:9,3) = colors(10,4:6);
            colors(10,4:6) = colors([9 8 7],7);
            colors(7:9,7) = tmp;
            colors(7:9,4:6) = colors([9 8 7],4:6)';
    end
end
if any(num==3)
    switch dir
        case 1
            changeColor(ph(13:15,9),ph(12,[6 5 4]));
            changeColor(ph(12,1:3),ph(7:9,1));
            changeColor(ph(1:3,1),ph(4,[6 5 4]));
            changeColor(ph(4,7:9),ph(7:9,9));
            up = [up; ph(7:9,9) ph(13:15,9)];
            down = [down; ph(1:3,1) ph(7:9,1)];
            right = [right ph(12,1:6)];
            left = [left ph(4,4:9)];
            cWise = [cWise ph(7:9,10:12)];
            tmp = colors(12,[6 5 4]);
            colors(12,4:6) = colors(7:9,1);
            colors(7:9,1) = colors(4,[6 5 4]);
            colors(4,4:6) = colors(7:9,9);
            colors(7:9,9) = tmp;
            colors(7:9,10:12) = colors([9 8 7],10:12)';
        case 2
            changeColor(ph(12,7:9),ph([9 8 7],9));
            changeColor(ph(1:3,9),ph(4,4:6));
            changeColor(ph(4,1:3),ph([9 8 7],1));
            changeColor(ph(13:15,1),ph(12,4:6));
            up = [up; ph(13:15,1) ph(7:9,1)];
            down = [down; ph(1:3,9) ph(7:9,9)];
            right = [right ph(4,1:6)];
            left = [left ph(12,4:9)];
            ccWise = [ccWise ph(7:9,10:12)];
            tmp = colors(4,4:6);
            colors(4,4:6) = colors([9 8 7],1);
            colors(7:9,1) = colors(12,4:6);
            colors(12,4:6) = colors([9 8 7],9);
            colors(7:9,9) = tmp;
            colors(7:9,10:12) = colors(7:9,[12 11 10])';
    end
end
if any(num==2)
    switch dir
        case 1
            changeColor(ph(13:15,8),ph(11,[6 5 4]));
            changeColor(ph(11,1:3),ph(7:9,2));
            changeColor(ph(1:3,2),ph(5,[6 5 4]));
            changeColor(ph(5,7:9),ph(7:9,8));
            up = [up; ph(7:9,8) ph(13:15,8)];
            down = [down; ph(1:3,2) ph(7:9,2)];
            right = [right ph(11,1:6)];
            left = [left ph(5,4:9)];
            tmp = colors(11,[6 5 4]);
            colors(11,4:6) = colors(7:9,2);
            colors(7:9,2) = colors(5,[6 5 4]);
            colors(5,4:6) = colors(7:9,8);
            colors(7:9,8) = tmp;
        case 2
            changeColor(ph(11,7:9),ph([9 8 7],8));
            changeColor(ph(1:3,8),ph(5,4:6));
            changeColor(ph(5,1:3),ph([9 8 7],2));
            changeColor(ph(13:15,2),ph(11,4:6));
            up = [up; ph(13:15,2) ph(7:9,2)];
            down = [down; ph(1:3,8) ph(7:9,8)];
            right = [right ph(5,1:6)];
            left = [left ph(11,4:9)];
            tmp = colors(5,4:6);
            colors(5,4:6) = colors([9 8 7],2);
            colors(7:9,2) = colors(11,4:6);
            colors(11,4:6) = colors([9 8 7],8);
            colors(7:9,8) = tmp;
    end
end

setappdata(gcf,'colors',colors);
if getappdata(gcf,'animation')
    animation(right,left,up,down,cWise,ccWise);
end
reColor(ph,colors);
switchCallBack('on');

%-----------------------------------------------------------

function colors=orientIt(obj,eventData,axis)

switch axis
    
    case 1
        moveX([],[],[1 2 3],1);
        colors=moveZ([],[],[1 2 3],2);
    case 2
        moveX([],[],[1 2 3],2);
        colors=moveZ([],[],[1 2 3],2);
    case 3
        moveY([],[],[1 2 3],1);
        colors=moveZ([],[],[1 2 3],2);
    case 4
        moveY([],[],[1 2 3],2);
        colors=moveZ([],[],[1 2 3],2);
    case 5
        moveZ([],[],[1 2 3],1);
        moveZ([],[],[1 2 3],1);
        colors=moveY([],[],[1 2 3],1);
    case 6
        moveZ([],[],[1 2 3],2);
        moveZ([],[],[1 2 3],2);
        colors=moveY([],[],[1 2 3],2);
    case 7
        moveZ([],[],[1 2 3],1);
        moveZ([],[],[1 2 3],1);
        colors=moveX([],[],[1 2 3],1);
    case 8
        moveZ([],[],[1 2 3],2);
        moveZ([],[],[1 2 3],2);
        colors=moveX([],[],[1 2 3],2);
    case 9
        moveX([],[],[1 2 3],2);
        moveZ([],[],[1 2 3],1);
        colors=moveY([],[],[1 2 3],1);
    case 10
        moveX([],[],[1 2 3],2);
        moveZ([],[],[1 2 3],2);
        colors=moveY([],[],[1 2 3],2);
    case 11
        colors=moveX([],[],[1 2 3],1);
    case 12
        colors=moveY([],[],[1 2 3],1);
    case 13
        colors=moveZ([],[],[1 2 3],1);
end

%----------------------------------------------------
function colorPalette(obj,eventData)

parentFig = gcf;
colorP = getappdata(parentFig,'colorP');
cubeSize = getappdata(parentFig,'cubeSize');
switchCallBack off

figH = figure('menubar','none',...
              'numbertitle','off',...
              'name','Color Selector',...
              'position',[200 200 6*cubeSize 11*cubeSize],...
              'closeRequestFcn',@CSCloseRequest, ...
              'windowstyle','modal');
          
aH = axes('units','pixels',...
          'position',[0 0 6*cubeSize 11*cubeSize],...
          'xlim',[0 6*cubeSize],...
          'ylim',[0 11*cubeSize],...
          'visible','off');
      
p(1) = patch([cubeSize 2*cubeSize 2*cubeSize cubeSize],...
             [8.5*cubeSize 8.5*cubeSize 9.5*cubeSize 9.5*cubeSize],...
             colorP(1,:));
p(2) = patch([cubeSize 2*cubeSize 2*cubeSize cubeSize],...
             [7*cubeSize 7*cubeSize 8*cubeSize 8*cubeSize],...
             colorP(2,:));
p(3) = patch([cubeSize 2*cubeSize 2*cubeSize cubeSize],...
             [5.5*cubeSize 5.5*cubeSize 6.5*cubeSize 6.5*cubeSize],...
             colorP(3,:));
p(4) = patch([cubeSize 2*cubeSize 2*cubeSize cubeSize],...
             [4*cubeSize 4*cubeSize 5*cubeSize 5*cubeSize],...
             colorP(4,:));
p(5) = patch([cubeSize 2*cubeSize 2*cubeSize cubeSize],...
             [2.5*cubeSize 2.5*cubeSize 3.5*cubeSize 3.5*cubeSize],...
             colorP(5,:));
p(6) = patch([cubeSize 2*cubeSize 2*cubeSize cubeSize],...
             [cubeSize cubeSize 2*cubeSize 2*cubeSize],...
             colorP(6,:));
         
bars(1).r = uicontrol('style','slider','value',colorP(1,1),'callback',{@CSChangeColor,1},...
                      'position',[3*cubeSize 9.2*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(1).g = uicontrol('style','slider','value',colorP(1,2),'callback',{@CSChangeColor,1},...
                      'position',[3*cubeSize 8.85*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(1).b = uicontrol('style','slider','value',colorP(1,3),'callback',{@CSChangeColor,1},...
                      'position',[3*cubeSize 8.5*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(2).r = uicontrol('style','slider','value',colorP(2,1),'callback',{@CSChangeColor,2},...
                      'position',[3*cubeSize 7.7*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(2).g = uicontrol('style','slider','value',colorP(2,2),'callback',{@CSChangeColor,2},...
                      'position',[3*cubeSize 7.35*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(2).b = uicontrol('style','slider','value',colorP(2,3),'callback',{@CSChangeColor,2},...
                      'position',[3*cubeSize 7*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(3).r = uicontrol('style','slider','value',colorP(3,1),'callback',{@CSChangeColor,3},...
                      'position',[3*cubeSize 6.2*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(3).g = uicontrol('style','slider','value',colorP(3,2),'callback',{@CSChangeColor,3},...
                      'position',[3*cubeSize 5.85*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(3).b = uicontrol('style','slider','value',colorP(3,3),'callback',{@CSChangeColor,3},...
                      'position',[3*cubeSize 5.5*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(4).r = uicontrol('style','slider','value',colorP(4,1),'callback',{@CSChangeColor,4},...
                      'position',[3*cubeSize 4.7*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(4).g = uicontrol('style','slider','value',colorP(4,2),'callback',{@CSChangeColor,4},...
                      'position',[3*cubeSize 4.35*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(4).b = uicontrol('style','slider','value',colorP(4,3),'callback',{@CSChangeColor,4},...
                      'position',[3*cubeSize 4*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(5).r = uicontrol('style','slider','value',colorP(5,1),'callback',{@CSChangeColor,5},...
                      'position',[3*cubeSize 3.2*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(5).g = uicontrol('style','slider','value',colorP(5,2),'callback',{@CSChangeColor,5},...
                      'position',[3*cubeSize 2.85*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(5).b = uicontrol('style','slider','value',colorP(5,3),'callback',{@CSChangeColor,5},...
                      'position',[3*cubeSize 2.5*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(6).r = uicontrol('style','slider','value',colorP(6,1),'callback',{@CSChangeColor,6},...
                      'position',[3*cubeSize 1.7*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(6).g = uicontrol('style','slider','value',colorP(6,2),'callback',{@CSChangeColor,6},...
                      'position',[3*cubeSize 1.35*cubeSize 2*cubeSize 0.3*cubeSize]);
bars(6).b = uicontrol('style','slider','value',colorP(6,3),'callback',{@CSChangeColor,6},...
                      'position',[3*cubeSize 1*cubeSize 2*cubeSize 0.3*cubeSize]);
                  
uicontrol('style','text','string','R','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 9.2*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','G','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 8.85*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','B','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 8.5*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','R','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 7.7*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','G','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 7.35*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','B','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 7*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','R','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 6.2*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','G','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 5.85*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','B','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 5.5*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','R','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 4.7*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','G','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 4.35*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','B','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 4*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','R','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 3.2*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','G','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 2.85*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','B','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 2.5*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','R','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 1.7*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','G','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 1.35*cubeSize 0.3*cubeSize 0.3*cubeSize]);
uicontrol('style','text','string','B','backgroundcolor',[0.8 0.8 0.8],...
          'position',[2.5*cubeSize 1*cubeSize 0.3*cubeSize 0.3*cubeSize]);
         
uicontrol('style','text','string','Scheme:','backgroundcolor',[0.8 0.8 0.8],...
          'fontunits','pixels','fontsize',0.3*cubeSize,...
          'position',[0.5*cubeSize 10*cubeSize 2*cubeSize 0.45*cubeSize]);
list = uicontrol('style','popupmenu','fontunits','pixels','fontsize',0.3*cubeSize,...
                 'string',{'Custom','Default','Cool','Hot','Bone','Copper','Pink','Gray','Lines','Hsv','Jet','Prism','Autumn','Winter','Summer','Spring'},...
                 'callback',@CSScheme,'value',getappdata(parentFig,'scheme'),...
                 'position',[2.5*cubeSize 10*cubeSize 2*cubeSize 0.5*cubeSize]);

         
setappdata(figH,'p',p);
setappdata(figH,'parentFig',parentFig);
setappdata(figH,'bars',bars);
setappdata(figH,'list',list);


%-----------------------------------------------------------------------
function CSChangeColor(obj,eventData,num,color)

bars = getappdata(gcf,'bars');
p = getappdata(gcf,'p');
parentFig = getappdata(gcf,'parentFig');
colorP = getappdata(parentFig,'colorP');
list = getappdata(gcf,'list');

if nargin==3
    color = [get(bars(num).r,'value') get(bars(num).g,'value') get(bars(num).b,'value')];
else
    set(bars(num).r,'value',color(1));
    set(bars(num).g,'value',color(2));
    set(bars(num).b,'value',color(3));
end

set(p(num),'faceColor',color);

colorP(num,:) = color;
setappdata(parentFig,'colorP',colorP);

colors = getappdata(parentFig,'colors');
for i1=1:prod(size(colors))
    if colors(i1).face==num
        colors(i1).color = color;
    end
end
setappdata(parentFig,'colors',colors);
set(list,'value',1);
setappdata(parentFig,'scheme',1);

%--------------------------------------------------------------------------
function CSCloseRequest(obj,eventData)

figH = gcf;
parentFig = getappdata(figH,'parentFig');
try
    colors = getappdata(parentFig,'colors');
    
    ph = getappdata(parentFig,'ph');
    
    figure(parentFig);
    reColor(ph,colors);
    switchCallBack on
catch
    %nothing
end
delete(figH);

%--------------------------------------------------------------------------
function CSScheme(obj,eventData)


maps = {'Custom','Default','cool','hot','bone',...
        'copper','pink','gray',...
        'lines','hsv','jet','prism','autumn',...
        'winter','summer','spring'};

num = get(gcbo,'value');
if num==1
    return
elseif num==2
    colorP = [0 1 0; ...
          1 1 0; ...
          1 0 0; ...
          1 1 1; ...
          0 0 1; ...
          1 0.5 0];
else
    colorP = feval(maps{num},6);
end

for i1 = 1:6
    CSChangeColor([],[],i1,colorP(i1,:));
end
set(gcbo,'value',num);
parentFig = getappdata(gcf,'parentFig');
setappdata(parentFig,'scheme',num);
setappdata(parentFig,'colorP',colorP);

%--------------------------------------------------------------------------
function menuAbout(obj,eventD)
s = ['flatRubiks is \copyright Trent Michael Russi, 2005.', 10, ...
     'http://www.troatie.com', 10 10, ...
     'The solution algorithm used is \copyright Mark Jeays.', 10, ...
     'http://jeays.net/rubiks.htm'];
opt.WindowStyle = 'normal';
opt.Interpreter = 'tex';
warning off
msgbox(s,'About','none',opt);
warning on

%--------------------------------------------------------------------------
function menuHelp(obj,eventD)
web flatRubiksHelp.html -helpbrowser

Contact us at files@mathworks.com