%function varargout = editor(varargin)
function varargout = editor(varargin)

if nargin == 0 | iscell(varargin{1}), % LAUNCH GUI

	editStart
	mission = [];

	if nargin == 0,
		clear global
		clear getLegs
		clear getGpsLegs
	else
		clear mission
		clear origin
		clear referenceLines
		clear auvMarks
	end
	rand('state',sum(100*clock))

	fig = openfig(mfilename,'reuse');

	% Generate a structure of handles to pass to callbacks, and store it. 
	handles = guihandles(fig);
	guidata(fig, handles);
	clearGui(handles)

	if nargout > 0
		varargout{1} = fig;
	end
	
	% Set icons
	set(handles.new_mission,'CData',double(imread('new.bmp'))/255)
	set(handles.update_button,'CData',double(imread('open.bmp'))/255)
	set(handles.save_button,'CData',double(imread('save.bmp'))/255)
	set(handles.clear_button,'CData',double(imread('clear.bmp'))/255)
	set(handles.work_site_button,'CData',double(imread('worksite.bmp'))/255)
	set(handles.utm_zone_button,'CData',double(imread('utm.bmp'))/255)
	set(handles.utm_plot_button,'CData',double(imread('plotutm.bmp'))/255)
	set(handles.geo_plot_button,'CData',double(imread('plotgeo.bmp'))/255)
	set(handles.struct_plot_button,'CData',double(imread('plotstruct.bmp'))/255)
	set(handles.move_up_button,'CData',double(imread('up.bmp'))/255)
	set(handles.move_down_button,'CData',double(imread('down.bmp'))/255)
	set(handles.delete_button,'CData',double(imread('delete.bmp'))/255)
	set(handles.cd_button,'CData',double(imread('cd.bmp'))/255)
	set(handles.quit_button,'CData',double(imread('quit.bmp'))/255)

	if nargin == 0, startWizard(fig, [], handles, varargin)
	else,
		global mission
		mission = varargin{1};
		update_behavior_list(handles)
		display_Callback(gcbo, [], handles, varargin)
		toggle_buttons(handles)
	end
    
elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

	try
		[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
	catch, errorbox, end

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function startWizard(h, eventdata, handles, varargin)
	global mission
quest = 'Would you like to plan a new survey or open an existing one?';
title = 'Welcome to the Bluefin Mission Editor.';
btn1 = 'Plan New Survey';
btn2 = 'Open Existing Survey';
btn3 = 'Cancel';
button = questdlg(quest,title,btn1,btn2,btn3,btn1);
if strcmp(button,btn1),
	new_button_Callback(h, eventdata, handles, varargin)
elseif strcmp(button,btn2),
	pause(0.1)
	load_button_Callback(h, eventdata, handles, varargin)
elseif strcmp(button,btn3),
	%put an action to Cancel here - close window?
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function editStart
[t,r]=strtok(fliplr(which('editor')),'\/');
editorPath = fliplr(r);
path(path,[editorPath 'behaviors'])
path(path,[editorPath 'geoutil'])
path(path,[editorPath 'icons'])
path(path,[editorPath 'io'])
path(path,[editorPath 'plot'])
path(path,[editorPath 'utils'])


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function clearGui(handles)
	global geoUnits

% Units
geoUnits = 'geo';

% Working directory
set(handles.directory_box,'String',pwd)

% Unselect listboxs
set(handles.behavior_index,'String','')
set(handles.listbox1,'Value',1.0)
set(handles.listbox2,'Value',1.0)
set(handles.listbox3,'Value',1.0)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function toggle_buttons(handles,value)
if nargin == 1, value = 'on'; end
set(handles.add_button,'Enable',value)
%set(handles.addRel_button,'Enable',value)
set(handles.edit_button,'Enable',value)
set(handles.copy_button,'Enable',value)
set(handles.move_up_button,'Enable',value)
set(handles.move_down_button,'Enable',value)
set(handles.delete_button,'Enable',value)
set(handles.delete_button2,'Enable',value)
set(handles.save_button,'Enable',value)
%set(handles.saven_button,'Enable',value)
set(handles.clear_button,'Enable',value)
%set(handles.utm_plot_button,'Enable',value)
%set(handles.geo_plot_button,'Enable',value)
set(handles.struct_plot_button,'Enable',value)
set(handles.utm_zone_button,'Enable',value)
set(handles.redo_button,'Enable',value)
set(handles.reset_button,'Enable',value)
%set(handles.block_button,'Enable',value)
set(handles.timer_button,'Enable',value)
%set(handles.add_field_button,'Enable',value)
%set(handles.remove_field_button,'Enable',value)
set(handles.work_site_button,'Enable',value)
set(handles.cvtUnits_button,'Enable',value)
set(handles.hide_defaults,'Enable',value)
set(handles.select_button,'Enable',value)
set(handles.sequence_radio,'Enable',value)
set(handles.layers_radio,'Enable',value)
set(handles.deg2dm_button,'Enable',value)
set(handles.dm2deg_button,'Enable',value)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function toggle_multiedit_buttons(handles,value)
if nargin == 1, value = 'on'; end
set(handles.add_button,'Enable',value)
%set(handles.addRel_button,'Enable',value)
set(handles.copy_button,'Enable',value)
set(handles.move_up_button,'Enable',value)
set(handles.move_down_button,'Enable',value)
set(handles.reset_button,'Enable',value)
%set(handles.block_button,'Enable',value)
%set(handles.add_field_button,'Enable',value)
%set(handles.remove_field_button,'Enable',value)
set(handles.select_button,'Enable',value)
set(handles.cvtUnits_button,'Enable',value)
set(handles.timer_button,'Enable',value)
set(handles.clear_button,'Enable',value)
set(handles.sequence_radio,'Enable',value)
set(handles.layers_radio,'Enable',value)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function toggle_header_buttons(handles,value)
if nargin == 1, value = 'on'; end
set(handles.add_button,'Enable',value)
%set(handles.addRel_button,'Enable',value)
set(handles.copy_button,'Enable',value)
set(handles.move_up_button,'Enable',value)
set(handles.move_down_button,'Enable',value)
set(handles.reset_button,'Enable',value)
%set(handles.block_button,'Enable',value)
%set(handles.add_field_button,'Enable',value)
%set(handles.remove_field_button,'Enable',value)
set(handles.select_button,'Enable',value)
set(handles.cvtUnits_button,'Enable',value)
set(handles.timer_button,'Enable',value)
set(handles.clear_button,'Enable',value)
set(handles.sequence_radio,'Enable',value)
set(handles.layers_radio,'Enable',value)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = load_button_Callback(h, eventdata, handles, varargin)
	global mission, global missionFile

if ~isempty(mission),
	str = 'Do you want to erase your existing mission?';
	button = questdlg(str);
	if ~strcmp(button,'Yes'), return, end
end
clear_button_Callback(h, eventdata, handles, varargin)
[mission,missionFile] = loadMissionFile(handles);
if isempty(mission) | isempty(missionFile), 
	toggle_buttons(handles,'off');
	return, end
bdefault = behaviorDefaults;
worksite = bdefault{findin(bdefault,'name','worksite')};
mission{1} = mergestructs(mission{1},worksite);
if isfield(mission{1},'numlegs'), getLegs('set',mission{1}.numlegs); end
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)
toggle_buttons(handles,'on')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [mission,file] = loadMissionFile(handles)
mission = [];
file = [];
filterSpec{1,1} = '*.cfg;*.mis';
filterSpec{1,2} = 'Bluefin mission file (*.cfg;*.mis)';
filterSpec{2,1} = 'routes32.txt';
filterSpec{2,2} = 'Maptech routes file (routes32.txt)';
filterSpec{3,1} = '*.pts';
filterSpec{3,2} = 'Winfrog survey file (*.pts)';
%filterSpec{4,1} = '*.mis';
%filterSpec{4,2} = 'Bluefin mission file (*.mis)';
[fname,pname] = uigetfile(filterSpec,'Choose file');
if fname == 0, return, end
try,
	pause(0.1), set(gcbf,'Pointer','watch')
	file = [pname fname];
    %evalin('base','cd(fileDlg(cd,[],''dirs'',cd))');
    cd(pname);
    set(handles.directory_box,'String',pname)
	if findstr(fname,'.cfg'), mission = readMissionFile(file);
	elseif findstr(fname,'.mis'), mission = readMissionFile(file);
    elseif findstr(fname,'.mis'), mission = readMissionFile(file);
	elseif findstr(fname,'.pts') mission = readWinfrogFile(file);
	elseif findstr(fname,'routes32'), mission = readMaptechFile(file); end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function update_behavior_list(handles)
	global mission
vars=mission{1}.name;
if get(handles.sequence_radio,'Value'), vec = length(mission):-1:2;
else vec = 2:length(mission); end
if get(handles.group_checkbox,'Value'),	
	[vars] = groupBehaviors(mission,handles);
else 
	for i=vec,vars=strvcat(vars,mission{i}.name); end
end
set(handles.listbox1,'String',vars)
set(handles.text1,'String',mission{1}.name)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = display_Callback(h, eventdata, handles, varargin)
	global mission
try,
[isheader, hindex, hnums] = checkHeaderIndex(handles,0);
if isheader>=1,
	if length(hindex) > 1, hindex = hindex(hnums(1)); end
	if (strcmp(get(gcbf,'SelectionType'),'open') & strcmp(get(gcbo,'Tag'),'listbox1')),
		[hindex] = getNewHeaderIndex(handles, hindex, get(handles.group_checkbox,'UserData'));
		set(handles.group_checkbox,'UserData',~get(handles.group_checkbox,'UserData'));
		update_behavior_list(handles)
		set(handles.listbox1,'Value',hindex);
	end
	display_header(handles, hindex); 
	return,
end
index = getBehaviorIndex(handles);
if isempty(index), return, end
set(handles.edit_text,'String','')
set(handles.text5,'String','','TooltipString','')
set(handles.text6,'String','','TooltipString','')
set(handles.text7,'String','','TooltipString','')

if length(index) > 1, 
	toggle_multiedit_buttons(handles,'off')
	set(handles.listbox2,'Enable','inactive')
	set(handles.behavior_index,'String','')
	return
else
	set(handles.listbox2,'Enable','on')
	toggle_multiedit_buttons(handles)
	set(handles.behavior_index,'String',mynum2str(index-1))
end
if index > length(mission),
	if isempty(mission), set(handles.listbox1,'String',''), end
	set(handles.listbox2,'String','')
	set(handles.listbox3,'String','')
	set(handles.listbox2,'Value',1);
	set(handles.listbox3,'Value',1);	
else
	bstruct = mission{index};
	if get(handles.hide_defaults,'Value') & index>1,
		bstruct = removeDefaults(bstruct);
	end
	attributes = fieldnames(bstruct);
	values = mystruct2cell(bstruct);
	index2 = get(handles.listbox2,'Value');
	if index2 > length(values), index2 = 1; end
	set(handles.listbox2,'Value',index2)
	set(handles.listbox3,'Value',index2)
	set(handles.listbox2,'String',attributes)
	set(handles.listbox3,'String',values)
	text_Callback(h,eventdata,handles,varargin);
end
catch, errorbox('display_Callback failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = edit_button_Callback(h, eventdata, handles, varargin)
	global mission
try,
[isheader, hindex, hnums] = checkHeaderIndex(handles,0);
if isheader > 0, return, end
index = getBehaviorIndex(handles);
if length(index) > 1,
	multiedit_button_Callback(h, eventdata, handles, varargin)
	return
end
if isempty(index), return, end
bstruct = mission{index};

if (length(fieldnames(bstruct)) > 15),
	bfields = fieldnames(bstruct);
	bvalues = mystruct2cell(bstruct);
	bstruct1 = cell2struct(bvalues(1:15),bfields(1:15));
	% for mission{1}:
	if (isfield(bstruct,'missiontype')), catbvalue = bvalues(1); else, catbvalue = bvalues(1); end
	bstruct2 = cell2struct(cat(1,catbvalue,bvalues(16:length(bfields))),cat(1,bfields(1),bfields(16:length(bfields))));
	[answer1,fields1] = editStruct(bstruct1);
	if isempty(answer1), return, end
	[answer2,fields2] = editStruct(bstruct2);
	if isempty(answer2), return, end
	answer = cat(1,answer1,answer2(2:length(answer2)));
	fields = cat(1,fields1,fields2(2:length(fields2)));
else
	[answer,fields] = editStruct(bstruct);
end
if isempty(answer), return, end
mission{index} = cell2struct(answer,fields);
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)
catch, errorbox('edit_button_Callback failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [answer,fields] = editStruct(bstruct,editName)
answer = []; fields = [];
try,
if nargin == 1, editName = 1; end
notes = get_text_struct(bstruct,behaviorNotes,'notes');
types = get_text_struct(bstruct,behaviorTypes,'types');
units = get_text_struct(bstruct,behaviorUnits,'units');
title  = 'Edit attributes';
if isfield(bstruct,'name'), title = [title ' ' bstruct.name]; end
if ~editName & isfield(bstruct,'name'),
	bstruct = rmfield(bstruct,'name');
end
if isempty(bstruct), return, end
fields = fieldnames(bstruct);
values = struct2cell(bstruct);
def = mystruct2cell(bstruct);
prompt = fields;
if ~isempty(notes) & ~isempty(types) & ~isempty(units),
	notenames = fieldnames(notes);
	typenames = fieldnames(types);
	unitnames = fieldnames(units);
	for i=1:length(prompt),
		pname = prompt{i};
		if ~strcmp(pname,'name'),
			if indexof(notenames,pname),
				str = getfield(notes,pname);
				if ~isempty(str), prompt{i} = [prompt{i} ': ' str]; end
			end
			if indexof(typenames,pname),
				str = getfield(types,pname);
				if ~isempty(str), prompt{i} = [prompt{i} ' -- ' str]; end
			end
			if indexof(unitnames,pname),
				str = getfield(units,pname);
				if ~isempty(str), prompt{i} = [prompt{i} ' (' str ')']; end
			end
		end		
	end
end
answer = inputdlg(prompt,title,1,def)
if isempty(answer), return, end
for i=1:length(answer),
	if ~ischar(values{i}), answer{i} = str2num(answer{i}); end
end
catch, errorbox('editStruct failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = multiedit_button_Callback(h, eventdata, handles, varargin)
	global mission
indices = getBehaviorIndex(handles);
bstruct = andStructs(mission(indices));
fields = fieldnames(bstruct);
if isfield(bstruct,'name') & length(fields) == 1, 
	helpdlg('No available fields to edit.','Multi Edit Button Help');
	return, 
end
[s,v] = listdlg('PromptString','Select attributes to edit:','ListString',fields);
if v == 0, return, end
editStr = [];
for i=1:length(s),
	editStr = setfield(editStr,fields{s(i)},getfield(bstruct,fields{s(i)}));		
end
[answer,fields] = editStruct(editStr,0);
if isempty(answer), return, end
bstruct = cell2struct(answer,fields);
fields = fieldnames(bstruct);
for i=1:length(indices),
	for j=1:length(fields),	
		mission{indices(i)} = setfield(mission{indices(i)}, ...
			fields{j}, getfield(bstruct,fields{j}));
	end
end
set(handles.listbox1,'Value',min(indices))
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function outstruct = get_text_struct(bstruct,textstruct,whichtext)
fields = fieldnames(bstruct);
outstruct = [];
name = getBehaviorName(bstruct);
bi = 0;
if ~isempty(name), bi = findin(textstruct,'name',name); end
if bi,
	outstruct = textstruct{bi};
	if strcmp(name,'ascend') | strcmp(name,'descend') | strcmp(name,'launch') | ...
		strcmp(name,'setdepth') | strcmp(name,'setelevator') | strcmp(name,'setpoint') | ...
		strcmp(name,'setrudder') | findstr(name,'trackline') | findstr(name,'waypoint') | ...
		strcmp(name,'wiggle') | findstr(name,'yoyo'),
		outstruct = addBlockDefaults(bstruct,outstruct,whichtext);
	end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function name = getBehaviorName(bstruct)
name = [];
if ~isfield(bstruct,'name'), return, end
if isfield(bstruct,'missiontype'),
	name = lower(bstruct.missiontype);
else name = lower(bstruct.name); end

if findstr(name,'.cfg'),
	name = 'worksite';
elseif strcmp(name,'trackline'),
	fields = fieldnames(bstruct);
	if indexof(fields,'northing'), name = 'tracklineutm';
	else name = 'tracklinegeo'; end
elseif strcmp(name,'waypoint'),
	fields = fieldnames(bstruct);
	if indexof(fields,'northing'), name = 'waypointutm';
	else name = 'waypointgeo'; end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = text_value_Callback(h, eventdata, handles, varargin)
index3 = get(handles.listbox3,'Value');
if isempty(index3), return, end
set(handles.listbox2,'Value',index3)
[isheader, hindex, hnums] = checkHeaderIndex(handles,0);
if isheader > 0, return, end
index1 = getBehaviorIndex(handles);
if isempty(index1), return, end
text_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = text_Callback(h, eventdata, handles, varargin)
	global mission
set(handles.edit_text,'String','')
set(handles.text5,'String','','TooltipString','')	
set(handles.text6,'String','','TooltipString','')
set(handles.text7,'String','','TooltipString','')

index2 = get(handles.listbox2,'Value');
if isempty(index2), return, end
set(handles.listbox3,'Value',index2)

[isheader, hindex, hnums] = checkHeaderIndex(handles,0);
if isheader > 0, return, end

index1 = getBehaviorIndex(handles);
if isempty(index1), return, end
bstruct = mission{index1};

vars = get(handles.listbox2,'String');
field = lower(vars{index2});
value = getfield(mission{index1},field);
set(handles.edit_text,'String',mynum2str(value))
if strcmp(field,'name'), return, end

notes = get_text_struct(bstruct,behaviorNotes,'notes');
if ~isempty(notes) & isfield(notes,vars{index2}),
	str = getfield(notes,field);
	set(handles.text5,'String',str,'TooltipString',str)
end

types = get_text_struct(bstruct,behaviorTypes,'types');
if ~isempty(types) & isfield(types,field),
	str = getfield(types,field);
	set(handles.text6,'String',str)
end

units = get_text_struct(bstruct,behaviorUnits,'units');
if ~isempty(units) & isfield(units,field),
	str = getfield(units,field);
	set(handles.text7,'String',str,'TooltipString',str)
	
end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = delete_button_Callback(h, eventdata, handles, varargin)
try,
	global mission
[isheader,hindex,hnums] = checkHeaderIndex(handles,0);
if isheader==1, delete_button_header(hindex,h, eventdata, handles, varargin); return;
elseif isheader==2, 
	helpdlg('Please select only groups or individual behaviors outside of a group','Delete Help');
	return;
end
index = get(handles.listbox1,'Value');
for ii=1:length(index),
	isgrouped = checkBehaviorGrouped(handles,index(ii)); % want to check display, not mission index
	if isgrouped, 
		helpdlg('You cannot delete a behavior that is part of a surveyleg.','Delete Help');
		return;
	end
end
[bindex,index] = getBehaviorIndex(handles);
if isempty(bindex) | bindex > length(mission), return, end
if find(bindex <= 1), 
	helpdlg('You cannot delete the survey definition section.','Delete Help');
	return, 
end

if length(bindex) > 1,
	str = 'Are you sure you want to delete these behaviors?';	
else
	str = 'Are you sure you want to delete this behavior?';
end

button = questdlg(str);
if ~strcmp(button,'Yes'), return, end
mission(bindex) = [];
update_behavior_list(handles)
if length(index) > 1, index = min(index); end
index = min(max(index,1),length(mission));
%set(handles.listbox1,'Value',index)
setBehaviorIndex(handles,index);
display_Callback(h, eventdata, handles, varargin)
catch, errorbox('delete_button_Callback failed'), end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = delete_button_header(hindex,h,eventdata,handles,varargin)
global numGroupBehaviors, global mission
try,
str = get(handles.listbox1,'String');
if length(hindex) > 1,
	hstr = '';
	for ii=1:length(hindex)-1,
		hstr = strcat(hstr,deblank(str(hindex(ii),:)),',');
	end
	hstr = strcat(hstr,deblank(str(hindex(length(hindex)),:)));
else
	hstr = deblank(str(hindex,:));
end
button=lower(questdlg(['Are you sure you want to delete ' hstr '?'], ...
	'Confirm Delete','No'));
if strcmp(button,'no') | strcmp(button,'cancel'), return, end

index = getSelectBehaviorIndex(handles,hindex(1));
headers = checkBehaviorIndex('headers',handles,0);
firsth = find(headers == hindex(1));
if ~isempty(index),
	for jj=1:length(hindex),
		% get correct header index
		currhindex = hindex(jj);
		% if jj>1, deleted last header, need to find new header index of next header to delete
		headers = checkBehaviorIndex('headers',handles,0);
		currhindex = headers(firsth);
		
		index = getSelectBehaviorIndex(handles,currhindex);
		endindex = index;
		if isempty(index), return, end;
		tindex = getHeaderLegNum(handles, currhindex, 1);
		numtodelete = numGroupBehaviors(tindex);
		if get(handles.sequence_radio,'Value'), inc = -1; else inc = 1; end
		endindex = index + numtodelete*inc;
		if (endindex <= 3), endindex = 4; end % dont delete mission header or depth envelope
		if get(handles.sequence_radio,'Value'), idel = endindex+1; else idel = index; end
		for ii=1:numtodelete,
			mission(idel) = [];
		end

		if length(hstr)>9,
			if strcmp(hstr(1:9),'surveyleg'),
				[numlegs] = getLegs('get',0);
				% account for criss cross
				if length(numlegs)>1,
					if tindex>numlegs(1),
						numlegs = [numlegs(1),numlegs(2)-1];
					else
						numlegs = [numlegs(1)-1,numlegs(2)];
					end
				else
					numlegs = numlegs - 1;
				end
				getLegs('set',numlegs);
				gpslegs = getGpsLegs('get',0);
				gpslegs(tindex) = [];
				getGpsLegs('clear',0);
				getGpsLegs('set',gpslegs);
			end
		end

		update_behavior_list(handles)
	end
	if numtodelete > 1, index = min(index,endindex); end
	index = min(max(index,1),length(mission));
	setBehaviorIndex(handles,index);
	display_Callback(h, eventdata, handles, varargin)
end
catch, errorbox('delete_button_header failed'), end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = add_button_Callback(h, eventdata, handles, varargin)
	global mission
index = getBehaviorIndex(handles);
if isempty(index),return, end
objnames = {'Behavior','Relative Behavior','Block'};
[s1,v] = listdlg('PromptString','Select an object to add:',...
	'SelectionMode','single','ListSize',[160 100],'ListString',objnames);
if v == 0, return, end

if s1 == 1,
	[bdefault,bnames] = behaviordefaults(1);
	[s,v] = listdlg('PromptString','Select a behavior:',...
	'SelectionMode','single','ListString',bnames);
	if v == 0, return, end
	[bindex,index] = getBehaviorIndex(handles);
	if isempty(index), return, end
	if index <= 1, index = 2; end
	if bindex <= 1, bindex = 2; end
	add_behavior(bdefault{s},bindex);
	%set(handles.listbox1,'Value',index+get(handles.sequence_radio,'Value'))
	setBehaviorIndex(handles,index+get(handles.sequence_radio,'Value'));
	update_behavior_list(handles)
	display_Callback(h, eventdata, handles, varargin)
elseif s1 == 2,
	addRel_button_Callback(h, eventdata, handles, varargin);
else
	block_button_Callback(h, eventdata, handles, varargin);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = addRel_button_Callback(h, eventdata, handles, varargin)
	global mission
index = getBehaviorIndex(handles);
[lat0,lon0] = getWaypoint(mission{index});
if isempty(lat0) | isempty(lon0), return, end
[bdefault,bnames] = behaviordefaults;
choices{1} = 'waypointgeo';
choices{2} = 'tracklinegeo';
[s,v] = listdlg('PromptString','Select a behavior:',...
	'SelectionMode','single','ListString',choices);
if v == 0, return, end
bstruct = bdefault{indexof(bnames,choices{s})};
editStruct = bdefault{indexof(bnames,'waypointrel')};
[answer,fields] = editStruct(editStruct,0);
if isempty(answer), return, end
[lat,lon] = reckon('rh',lat0,lon0,answer{1},answer{2},selectGeoid);
bstruct.latitude = lat;
bstruct.longitude = lon;
if strcmp(bstruct.name,'trackline'),
	bstruct.initiallat = lat0;
	bstruct.initiallong = lon0;
end
if index <= 1, index = 2; end
add_behavior(bstruct,index);
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [lat,lon] = getWaypoint(bstruct)
lat = [];
lon = [];
bstruct = butm2geo(bstruct,getUtmStruct);
if isfield(bstruct,'latitude'), lat = bstruct.latitude; end
if isfield(bstruct,'longitude'), lon = bstruct.longitude; end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = timer_button_Callback(h, eventdata, handles, varargin)
index = set_timeout(handles);
setBehaviorIndex(handles,index)
set(handles.listbox2,'Value',1)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function index = set_timeout(handles)
	global mission		
total = 0;
for i=1:length(mission),
	fields = fieldnames(mission{i});
	if isfield(mission{i},'duration'),
		val = getfield(mission{i},'duration');
		if isempty(val),
			uiwait(msgbox([mission{i}.name ' (' int2str(i) ') duration not set'], ...
				'modal'))
			index = i;
			return
		end
		if ischar(val), val = str2num(val); end
		total = total + val;
	end
end
index = findin(mission,'name','missiontimer');
if index<1,
	uiwait(msgbox('Mission timer not found','modal'))
	return
end
if ~isfield(mission{index},'timeout'),
	uiwait(msgbox('Mission timer needs a timeOut','modal'))
	return
end
mission{index}.timeout = total;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function add_behavior(bstruct,index)
	global mission
n = length(mission);
index = max(index,1);
if n < 1,
	mission{1} = bstruct;
	return
end
if index > n,
	mission{n+1} = bstruct;
else
	tmp = mission(1:index-1);
	tmp{index} = bstruct;
	tmp(index+1:n+1) = mission(index:end);
	mission = tmp;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = utm_plot_button_Callback(h, eventdata, handles, varargin)	
	global mission
try,
	ltm(0);
	if ~isempty(mission),
		cvt2utm
		utmFig('createPlot_Callback',[],[],[])
		display_Callback(h, eventdata, handles, varargin)
	else
		utmfig
	end
catch, errorbox('utm_plot_button_Callback failed'), end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = geo_plot_button_Callback(h, eventdata, handles, varargin)	
	global mission
try,
	ltm(0);
	if ~isempty(mission),
		if cvt2geo, geoFig('createPlot_Callback',[],[],[]), end
		display_Callback(h, eventdata, handles, varargin)
	else
		geofig
	end
catch, errorbox('geo_plot_button_Callback failed'), end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = struct_plot_button_Callback(h, eventdata, handles, varargin)	
try,
	if ltm(1) == -1, plotStruct, end
catch, errorbox('struct_plot_button_Callback failed'), end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = utm_zone_button_Callback(h, eventdata, handles, varargin)	
	global mission
button = questdlg('What would you like to select?','','UTM Zone','Chart','UTM Zone');
if strcmp(button,'Chart'), selectChart; return, end
zone = utmzone;
if isempty(zone), return, end
mission{1}.utmzone = zone;
set(handles.listbox1,'Value',1)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = editBehavior(mission,bname,ii)
if nargin == 2,
	ii = findin(mission,'name',bname,1);
end
if ii <= 0, return, end
[answer,fields] = editStruct(mission{ii},0);
if ~isempty(answer), 
	for jj=1:length(fields),
		mission{ii} = setfield(mission{ii},fields{jj},answer{jj});
	end	
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = editBehaviorStruct(mission,bstruct,ii)
if isempty(bstruct), return, end
if nargin == 2,
	ii = findin(mission,'name',bstruct.name,1);
end
if ii <= 0, return, end
ii = findin(mission,'name',bstruct.name,1);
if ii > 0,
	[answer,fields] = editStruct(bstruct,0);
	mission{ii} = setParameters(mission{ii},answer,fields);
end
		

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = new_button_Callback(h, eventdata, handles, varargin)	
	global mission
options{1} = 'Basic';
options{2} = 'Survey';
options{3} = 'SurveyBox';
options{4} = 'SurveyArea';
options{5} = 'SurveyAreaEZ';
options{6} = 'SurveyAreaOneway';
options{7} = 'CrissCross';
options{8} = 'QRoute';
options{9} = 'QRouteRelative';
options{10} = 'CompassStar';
options{11} = 'SurveyAreaRaw';
[s,v] = listdlg('PromptString','Select type of mission:',...
	'SelectionMode','single','ListString',options);
if ~v, return, end
clear_button_Callback(h, eventdata, handles, varargin)
mission = feval([lower(options{s}) 'Mission'],handles);
if s > 1, set_timeout(handles); end
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)
toggle_buttons(handles)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = redo_button_Callback(h, eventdata, handles, ...
	varargin)
	global mission
button = questdlg(strvcat('Are you sure you want to redo this mission? ', ...
	'Your current mission will not be saved.'));
if ~strcmp(button,'Yes'), return, end
if ~isfield(mission{1},'missiontype'),
	errorbox('Mission type ("missiontype") not found in mission{1}.')
	return
end
ii = findin(mission,'name','depthenvelope',1);
if ii > 0, bdepthenvelope = mission{ii};
else bdepthenvelope = []; end
ii = findin(mission,'name','controlsonar',1);
if ii > 0, bcontrolsonar = mission{ii};
else bcontrolsonar = []; end
ii = findin(mission,'name','controlsonaredgetech',1);
if ii > 0, bcontrolsonar = mission{ii};
else bcontrolsonar = []; end
mtype = getfield(mission{1},'missiontype');
bmission = mission{1};
clear_button_Callback(h, eventdata, handles, varargin)
if strcmp(mtype,'basic'),
	mission = basicMission(bdepthenvelope);
else
	mission = feval([mtype 'Mission'],handles,bdepthenvelope,bmission,bcontrolsonar);
end
set_timeout(handles);
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)
toggle_buttons(handles)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = basicMission(bdepthenvelope)
mission = [];
bdefault = behaviorDefaults;
mission{1} = bdefault{findin(bdefault,'name','worksite')};
mission{2} = bdefault{findin(bdefault,'name','missiontimer')};
default_depthenvelope = bdefault{findin(bdefault,'name','depthenvelope')};
default_depthenvelope = rmfield(default_depthenvelope,'debug');
if ~nargin | isempty(bdepthenvelope),
	mission{3} = default_depthenvelope;
else
	mission{3} = fillStruct(default_depthenvelope,bdepthenvelope);
end
mission{1}.name = 'untitled.mis';
mission{1}.author = '*';
mission{1}.missiontype = 'basic';
[answer,fields] = editStruct(mission{3},0);
if isempty(answer), return, end
for i=1:length(fields),
	mission{3} = setfield(mission{3},fields{i},answer{i});
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = surveyMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','survey')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	mission = [mission survey(answer{2},answer{3},answer{4}, ...
		answer{5}, answer{6},answer{7},answer{8},answer{9},answer{10}, ...
		answer{11},answer{12},answer{13})];
	mission{1}.name = answer{1};		
	mission{1}.missiontype = 'survey'; 
	mission{1} = setParameters(mission{1},answer,fields);
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = surveyboxMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','surveybox')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	mission = [mission surveyBox(answer{2},answer{3},answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9},answer{10}, ...
		answer{11},answer{12})];
	mission{1}.name = answer{1};
	mission{1}.missiontype = 'surveybox';
	mission{1} = setParameters(mission{1},answer,fields);
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = surveyareaMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','surveyarea')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	mission = [mission surveyArea(answer{2},answer{3},answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9},answer{10}, ...
		answer{11},answer{12},answer{13},answer{14})];
	mission{1}.name = answer{1};
	mission{1}.missiontype = 'surveyarea';
	mission{1} = setParameters(mission{1},answer,fields);	
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = surveyareaezMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','surveyareaez')};

if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	missionheader = mission;
	[mission,rng] = surveyAreaEZ(answer{2},answer{3},answer{4}, ...
			answer{5},answer{6},answer{7},answer{8},answer{9},answer{10}, ...
			answer{11},answer{12},answer{13});
	if isempty(mission), 
		mission = missionheader;
		set(gcbf,'Pointer','arrow');
		return,
	end
	mission = [missionheader mission];
	
	mission{1}.name = answer{1};
	mission{1}.missiontype = 'surveyareaez';
	mission{1} = setParameters(mission{1},answer,fields);
	mission{1}.numlegs = getLegs('get',0);
	mission{1}.tracklead = rng(1);
	mission{1}.trackspacing1 = rng(2);
	mission{1}.trackspacing2 = rng(3);
	if ~strcmp(sonarType,'none'),
	default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
	if nargin == 1 | isempty(bcontrolsonar),
		if strcmp(sonarType,'controlsonar'), %Klein
			default_sonar = setfield(default_sonar,'setrange',answer{8});
			default_sonar = setfield(default_sonar,'setmode','normal');
			default_sonar = setfield(default_sonar,'setresolution','0');
			default_sonar = rmfield(default_sonar,'logging');
			default_sonar = rmfield(default_sonar,'snapshot');
			default_sonar = rmfield(default_sonar,'debug');
		end
        	if strcmp(sonarType,'controlsonaredgetech'), %Edgetech
			default_sonar = setfield(default_sonar,'setmodesbp','on');
			default_sonar = setfield(default_sonar,'setmodessl','on');
			default_sonar = setfield(default_sonar,'setmodessh','on');
			default_sonar = setfield(default_sonar,'sbppingrate',4);
			default_sonar = setfield(default_sonar,'sslpingrange',100);
			default_sonar = setfield(default_sonar,'sshpingrange',100);
		end
		mission = editBehaviorStruct(mission,default_sonar);
	else
		bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
		mission = editBehaviorStruct(mission,bcontrolsonar);
	end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = crisscrossMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','crisscross')};

if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	missionheader = mission;
	mission = surveyCrissCross(answer{2},answer{3},answer{4}, ...
			answer{5},answer{6},answer{7},answer{8},answer{9},answer{10}, ...
			answer{11},answer{12},answer{13});
	if isempty(mission), 
		mission = missionheader;
		set(gcbf,'Pointer','arrow');
		return,
	end
	mission = [missionheader mission];
	
	mission{1}.name = answer{1};
	mission{1}.missiontype = 'crisscross';
	mission{1} = setParameters(mission{1},answer,fields);
	
	mission{1}.numlegs = getLegs('get',0);
	
	if ~strcmp(sonarType,'none'),
	default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
	if nargin == 1 | isempty(bcontrolsonar),
		if strcmp(sonarType,'controlsonar'), %Klein
			default_sonar = setfield(default_sonar,'setrange',answer{8});
			default_sonar = setfield(default_sonar,'setmode','normal');
			default_sonar = setfield(default_sonar,'setresolution','0');
			default_sonar = rmfield(default_sonar,'logging');
			default_sonar = rmfield(default_sonar,'snapshot');
			default_sonar = rmfield(default_sonar,'debug');
		end
        	if strcmp(sonarType,'controlsonaredgetech'), %Edgetech
			default_sonar = setfield(default_sonar,'setmodesbp','on');
			default_sonar = setfield(default_sonar,'setmodessl','on');
			default_sonar = setfield(default_sonar,'setmodessh','on');
			default_sonar = setfield(default_sonar,'sbppingrate',4);
			default_sonar = setfield(default_sonar,'sslpingrange',100);
			default_sonar = setfield(default_sonar,'sshpingrange',100);
		end
		mission = editBehaviorStruct(mission,default_sonar);
	else
		bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
		mission = editBehaviorStruct(mission,bcontrolsonar);
	end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = surveyareaonewayMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','surveyareaoneway')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	mission = [mission surveyAreaOneway(answer{2},answer{3},answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9},answer{10}, ...
		answer{11},answer{12},answer{13},answer{14})];
	mission{1}.name = answer{1};
	mission{1}.missiontype = 'surveyareaoneway';
	mission{1} = setParameters(mission{1},answer,fields);
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = surveyarea4leafMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
    global sonarType    
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','surveyarea4leaf')};
if nargin == 1,
    mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
    mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
pause(0.1), set(gcbf,'Pointer','watch')
mission = [mission surveyArea4Leaf(answer{2},answer{3},answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9})];
mission{1}.name = answer{1};
mission{1}.missiontype = 'surveyarea4leaf';
mission{1} = setParameters(mission{1},answer,fields);	
if ~strcmp(sonarType,'none'),
	if nargin == 1 | isempty(bcontrolsonar),
		mission = editBehavior(mission,sonarType);
	else
		default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
		bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
		mission = editBehaviorStruct(mission,bcontrolsonar);
	end
end
catch, errorbox, end
set(gcbf,'Pointer','arrow')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = surveyarearawMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
    global sonarType    
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','surveyarearaw')};
if nargin == 1,
    mission = basicMission;
else
    mission = basicMission(bdepthenvelope);
end
try
pause(0.1), set(gcbf,'Pointer','watch')
mission = [mission surveyAreaRaw]; 
mission{1}.missiontype = 'surveyarearaw';
if ~strcmp(sonarType,'none'),
	if nargin == 1 | isempty(bcontrolsonar),
		mission = editBehavior(mission,sonarType);
	else
		default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
		bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
		mission = editBehaviorStruct(mission,bcontrolsonar);
	end
end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = qrouteMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','qroute')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	mission = [mission qroute(str2num(answer{2}),str2num(answer{3}),answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9},answer{10}, ...
		answer{11},answer{12})];
	mission{1}.name = answer{1};
	mission{1}.missiontype = 'qroute';
	mission{1} = setParameters(mission{1},answer,fields);	
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = qrouterelativeMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','qrouterelative')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	[qroute,lat,lon] = qrouteRelative(answer{2},answer{3},answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9},answer{10}, ...
		answer{11},answer{12},answer{13},answer{14},answer{15});
	mission = [mission qroute];
	mission{1}.name = answer{1};
	mission{1}.missiontype = 'qrouterelative';
	mission{1}.latitude = lat;
	mission{1}.longitude = lon;
	mission{1} = setParameters(mission{1},answer,fields);
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end	
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = compasscircleMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','compasscircle')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	mission = [mission compasscircle(answer{2},answer{3},answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9},answer{10})];
	mission{1}.name = answer{1};		
	mission{1}.missiontype = 'compasscircle';
	mission{1} = setParameters(mission{1},answer,fields);	
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mission = compassstarMission(handles,bdepthenvelope,bmission, ...
	bcontrolsonar)
global sonarType
bdefaults = behaviorDefaults;
bstruct = bdefaults{findin(bdefaults,'name','compassstar')};
if nargin == 1,
	mission = basicMission;
else
	bstruct = fillStruct(bstruct,bmission);
	mission = basicMission(bdepthenvelope);
end
[answer,fields] = editStruct(bstruct,0);
if isempty(answer), return, end
try
	pause(0.1), set(gcbf,'Pointer','watch')
	mission = [mission compassstar(answer{2},answer{3},answer{4}, ...
		answer{5},answer{6},answer{7},answer{8},answer{9},answer{10})];
	mission{1}.name = answer{1};	
	mission{1}.missiontype = 'compassstar';
	mission{1} = setParameters(mission{1},answer,fields);	
	if ~strcmp(sonarType,'none'),
		if nargin == 1 | isempty(bcontrolsonar),
			mission = editBehavior(mission,sonarType);
		else
			default_sonar = bdefaults{findin(bdefaults,'name',sonarType)};
			bcontrolsonar = fillStruct(default_sonar,bcontrolsonar);
			mission = editBehaviorStruct(mission,bcontrolsonar);
		end
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')

	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bstruct = setParameters(bstruct,answer,fields)
for ii=2:length(answer),
	bstruct = setfield(bstruct,fields{ii},answer{ii});
end
	
	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = save_button_Callback(h, eventdata, handles, ...
	varargin)
	global mission, global missionFile
[mission,missionFile] = save_mission(mission, h, eventdata, ...
	handles, varargin);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = saven_button_Callback(h, eventdata, handles, ...
	varargin)
	global mission, global missionFile
prompt = {'Number of missions to create:'};
title = ['Subdivide and save ' mission{1}.name];
defans = {''};
response = inputdlg(prompt,title,1,defans);
if isempty(response), return, end
nMissions = response{1};
if isempty(nMissions), return, end
if ischar(nMissions), nMissions = str2num(nMissions); end
missions = splitMission(mission,nMissions);
if isempty(missions), return, end
for ii=length(missions):-1:1,
	save_mission(missions{ii}, h, eventdata, ...
		handles, varargin);
end
	

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [mission,missionFile] = save_mission(mission, h, eventdata, ...
	handles, varargin)
file = [];
missionFile = [];
misName = mission{1}.name;
if isempty(findstr(misName,'.mis')), misName = [misName '.mis']; end
filterSpec{1,1} = '*.mis';
filterSpec{1,2} = ['Bluefin mission file (' misName ')'];
filterSpec{2,1} = 'worksite.cfg';
filterSpec{2,2} = ['Bluefin worksite file (workSite.cfg)'];
filterSpec{3,1} = 'routes32.txt';
filterSpec{3,2} = 'Maptech routes file (routes32.txt)';
filterSpec{4,1} = '*.pts';
filterSpec{4,2} = 'Winfrog survey file (*.pts)';
filterSpec{5,1} = '*.txt';
filterSpec{5,2} = ['Text file (' misName '.txt)'];
[fname,pname] = uiputfile(filterSpec,['Save mission ' misName ' as:']);
if fname == 0, return, end
try,
	pause(0.1), set(gcbf,'Pointer','watch')
	file = [pname fname];
	writeSuccessful = 0;
	if findstr(fname,'routes32'),
		tmp = mission;
		if cvt2geo,
			[writeSuccessful,mission,missionFile] = writeMaptechFile(mission,file);
			tmp{1}.utmzone = mission{1}.utmzone;
		end
		mission = tmp;
	elseif findstr(lower(fname),'worksite'),
		[writeSuccessful,mission,missionFile] = writeWorksiteFile(mission,file, ...
			get(handles.hide_defaults,'Value'));		
	elseif findstr(fname,'.pts')
		tmp = mission;
		if cvt2geo,
			[writeSuccessful,mission,missionFile] = writeWinfrogFile(mission,file);
			tmp{1}.utmzone = mission{1}.utmzone;
		end
		mission = tmp;	
	elseif findstr(fname,'.txt')
		[writeSuccessful,mission,missionFile] = writeRouteFile(mission,file);
	else
		[writeSuccessful,mission,missionFile] = writeMissionFile(mission,file, ...
			get(handles.hide_defaults,'Value'));

	end
	if writeSuccessful > 0,
		set(handles.listbox1,'Value',1); 
		update_behavior_list(handles)
		display_Callback(h, eventdata, handles, varargin)
	end
catch, errorbox, end
set(gcbf,'Pointer','arrow')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = copy_button_Callback(h, eventdata, handles, varargin)
	global mission
[isheader,hindex,hnums] = checkHeaderIndex(handles,0);
if isheader >=1, return, end
[bindex,index] = getBehaviorIndex(handles);
if isempty(index), return, end
add_behavior(mission{bindex},bindex);
setBehaviorIndex(handles,index+1); %set(handles.listbox1,'Value',index+1);
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = move_up_button_Callback(h, eventdata, handles, varargin)
[isheader,hindex,hnums] = checkHeaderIndex(handles,0);
if isheader >1, return, end
if isheader, move_up_header(hindex, h, eventdata, handles, varargin); return; end
if get(handles.sequence_radio,'Value'),
	move_up_sequence(h, eventdata, handles, varargin)
else
	move_up_layers(h, eventdata, handles, varargin)
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function move_up_layers(h, eventdata, handles, varargin)
	global mission
[bindex,index] = getBehaviorIndex(handles);
if isempty(bindex), return, end
if bindex <= 2, return, end
% need to check if index will be going through a group
% if so, need to jump num behaviors, not just one.
if get(handles.group_checkbox,'Value'), numtojump = getNumtoJumpUp(handles,bindex);
else numtojump=-1; end
if numtojump == 0, return; end
bstruct = mission{bindex};
add_behavior(bstruct,bindex+numtojump)
mission(bindex+1) = [];
update_behavior_list(handles)
setBehaviorIndex(handles,bindex+numtojump); %set(handles.listbox1,'Value',index-1)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function move_up_sequence(h, eventdata, handles, varargin)
	global mission
[bindex,index] = getBehaviorIndex(handles);
if isempty(bindex), return, end
if bindex <= 2, return, end
bstruct = mission{bindex};
if get(handles.group_checkbox,'Value'), numtojump = getNumtoJumpUp(handles,index); 
else numtojump=2; end
if numtojump == 0, return; end
add_behavior(bstruct,bindex+numtojump)
mission(bindex) = [];
update_behavior_list(handles)
setBehaviorIndex(handles,bindex+numtojump-1); %set(handles.listbox1,'Value',index-1)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [numtojump] = getNumtoJumpUp(handles,index)
global numGroupBehaviors
% index: index to move, as a mission{} index

numtojump = 0;
isgrouped = checkBehaviorGrouped(handles,0);
if isgrouped, 
	helpdlg('You cannot move a behavior that is part of a surveyleg.','Move Up Help');
	return;
end
indexdisp = get(handles.listbox1,'Value');
headers = checkBehaviorIndex('headers',handles,0);

isgrouped = checkBehaviorGrouped(handles,indexdisp-1);
[isheader,hindex,hnums] = checkHeaderIndex(handles,indexdisp-1);
if get(handles.sequence_radio,'Value'),
	% +1
	if isheader,
		tindex = getHeaderLegNum(handles, indexdisp-1, 1);
		numtojump = numGroupBehaviors(tindex) + 1;
	elseif isgrouped,
		tindex = length(find(headers<indexdisp));
		numtojump = numGroupBehaviors(tindex) + 1;
	else
		numtojump = 2;
	end
else
	% -1
	numbehaviors = fliplr(numGroupBehaviors);
	if isheader,
		tindex = getHeaderLegNum(handles, indexdisp-1, 1);
		numtojump = -1*numGroupBehaviors(tindex);
	elseif isgrouped, % find previous header and jump the group
		tindex = length(find(headers < indexdisp));
		numtojump = -1*numbehaviors(tindex);
	else
		numtojump = -1;
	end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function move_up_header(hindex, h, eventdata, handles, varargin)
try,
global mission, global numGroupBehaviors

gpslegs = getGpsLegs('get',0);
tindex = getHeaderLegNum(handles, hindex, 1);
numtomove = numGroupBehaviors(tindex);

index = getSelectBehaviorIndex(handles,0); % get mission index of first behavior in this group
endindex = index;
if isempty(index), return, end
headers = checkBehaviorIndex('headers',handles,0);
if get(handles.sequence_radio,'Value'), inc = -1; else inc = 1; end
numtoshift = 0;
tindexflip = find(headers == hindex);
if tindexflip <= length(headers) & tindexflip > 1,
	if ~get(handles.group_checkbox,'UserData'),
		if (headers(tindexflip-1)==(hindex-(numGroupBehaviors(tindex+inc)+1))),
			% need to jump a group, not just index;
			numtoshift = numGroupBehaviors(tindex+inc);
		end
	else
		if (headers(tindexflip-1)==(hindex-1)),
			% need to jump a group, not just index;
			numtoshift = numGroupBehaviors(tindex+inc);
		end
	end
end
% add extra behavior group, then delete the old one
if ~isempty(index),
	if get(handles.sequence_radio,'Value'),

		if numtoshift == 0, numtoshift = 1; end
		istart = index;
		if index >= length(mission), return, end

		for ii=0:numtomove-1,
			bstruct = mission{istart - ii};
			
			add_behavior(bstruct,(istart+numtoshift+1));
		end
		for ii=1:numtomove,
			mission(istart-numtomove+1) = [];
		end
	else 		% Layers
		istart = index;
		if index <= 2, return, end
		if numtoshift == 0, numtoshift = 1; end
		for ii=0:numtomove-1,
			bstruct = mission{istart + (ii*2)}; % since you are adding behaviors previous to this index, the index will always equal the starting i
			shiftedindex = istart + (ii*2);
			addedindex = (istart+ii)-numtoshift;
			add_behavior(bstruct,((istart+ii)-numtoshift));
		end
		for ii=1:numtomove,
			deleted = istart+numtomove;
			deletedname = mission{deleted}.name;
			mission(istart+numtomove) = [];
		end
	end
	if tindexflip > 1,
		if numtoshift == 1, numtoshift = 0; end
		if (headers(tindexflip-1)==(hindex-numtoshift-1) | headers(tindexflip-1)==(hindex-1)),
			% need to jump a group, not just index;
			tmp = gpslegs(tindex+inc);
			gpslegs(tindex+inc) = gpslegs(tindex);
			gpslegs(tindex) = tmp;
			getGpsLegs('clear',0);
			getGpsLegs('set',gpslegs);
		end
	end
end
if numtoshift == 0, numtoshift = 1; end

update_behavior_list(handles)
% get the new set
headers = checkBehaviorIndex('headers',handles,0);
% find position
hposition = headers(tindexflip);
if numtoshift == 1,
	set(handles.listbox1,'Value',hposition);
else
	set(handles.listbox1,'Value',hposition-1);
end
display_Callback(h, eventdata, handles, varargin)


% where are you moving it? is the next index a header too? (collapsed)
% if not, just move group down one. if so, move group down the whole group.

catch, errorbox('move_up_header failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = move_down_button_Callback(h, eventdata, handles, varargin)
[isheader,hindex,hnums] = checkHeaderIndex(handles,0);
if isheader >1, return, end
if isheader, move_down_header(hindex,h, eventdata, handles, varargin); return; end
if get(handles.sequence_radio,'Value'),
	move_down_sequence(h, eventdata, handles, varargin)
else
	move_down_layers(h, eventdata, handles, varargin)
end

	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = move_down_layers(h, eventdata, handles, varargin)
	global mission	
index = getBehaviorIndex(handles);
if isempty(index), return, end
if index <= 1, return, end
if index >= length(mission), return, end
bstruct = mission{index};
if get(handles.group_checkbox,'Value'), numtojump = getNumtoJumpDown(handles,index,'layers'); 
else numtojump=2; end
if numtojump == 0, return; end
add_behavior(bstruct,index+numtojump)
mission(index) = [];
%set(handles.listbox1,'Value',index+1)
update_behavior_list(handles)
setBehaviorIndex(handles,index+numtojump-1);
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = move_down_sequence(h, eventdata, handles, varargin)
	global mission	
[bindex,index] = getBehaviorIndex(handles);
if isempty(index), return, end
if index == 1 | index == length(mission), return, end
bstruct = mission{bindex};
if get(handles.group_checkbox,'Value'), numtojump = getNumtoJumpDown(handles,index,'sequence'); 
else numtojump=-1; end
if numtojump == 0, return; end
add_behavior(bstruct,bindex+numtojump)
mission(bindex+1) = [];
%set(handles.listbox1,'Value',index+1)
update_behavior_list(handles)
setBehaviorIndex(handles,bindex+numtojump);
display_Callback(h, eventdata, handles, varargin)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [numtojump] = getNumtoJumpDown(handles,index,str1)
global numGroupBehaviors
% str1: 'layers' or 'sequence'
numtojump = 0;
isgrouped = checkBehaviorGrouped(handles,0);
if isgrouped, 
	helpdlg('You cannot move a behavior that is part of a surveyleg.','Move Down Help');
	return;
end
indexdisp = get(handles.listbox1,'Value');
headers = checkBehaviorIndex('headers',handles,0);

isgrouped = checkBehaviorGrouped(handles,indexdisp+1);
[isheader,hindex,hnums] = checkHeaderIndex(handles,indexdisp+1);

	if get(handles.sequence_radio,'Value'),
		% -1
		if isheader,
			tindex = getHeaderLegNum(handles, indexdisp+1, 1);
			numtojump = -1*numGroupBehaviors(tindex);
		elseif isgrouped,
			tindex = length(find(headers<indexdisp));
			numtojump = -1*numGroupBehaviors(tindex);
		else
			numtojump = -1;
		end
		
	else
		% +1
		numbehaviors = fliplr(numGroupBehaviors);
		if isheader,
			tindex = getHeaderLegNum(handles, indexdisp+1, 1);
			numtojump = numGroupBehaviors(tindex) + 1;
		elseif isgrouped,
			tindex = length(find(headers<indexdisp)) + 1;
			numtojump = numbehaviors(tindex) + 1;
		else
			numtojump = 2;
		end
	end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function move_down_header(hindex,h, eventdata, handles, varargin)
try,
global mission, global numGroupBehaviors
% will only get here if group checkbox checked.
% could be expanded or collapsed though
% also sequence vs. layers
% when moving a header, want to move underlying behaviors in the mission
% num behaviors will be automatically updated
% but will need to redo gpslegs - that is currently what numbehaviors depends on
gpslegs = getGpsLegs('get',0);
tindex = getHeaderLegNum(handles, hindex, 1);
numtomove = numGroupBehaviors(tindex);

index = getSelectBehaviorIndex(handles,0); % get mission index of first behavior in this group
endindex = index;

headers = checkBehaviorIndex('headers',handles,0);
if get(handles.sequence_radio,'Value'), inc = 1; else inc = -1; end
numtoshift = 0;
tindexflip = find(headers == hindex);
if tindexflip < length(headers),
	if ~get(handles.group_checkbox,'UserData'),
		if (headers(tindexflip+1)==(hindex+numtomove+1)),
			% need to jump a group, not just index;
			numtoshift = numGroupBehaviors(tindex+inc);
		end
	else
		if (headers(tindexflip+1)==(hindex+1)),
			% need to jump a group, not just index;
			numtoshift = numGroupBehaviors(tindex+inc);
		end
	end
end

% add extra behavior group, then delete the old one
if ~isempty(index),
	if get(handles.sequence_radio,'Value'),
		if index == 1 | index == length(mission), return, end
		%endindex = index + numtomove*(-1) + 1
		%if (endindex < 3), endindex = 3; end % dont delete mission header or depth envelope
		istart = index; % index will be 51 - need to go backwards
		ishift = -1;
		if numtoshift == 0, numtoshift = 1; end
		for ii=0:numtomove-1,
			bstruct = mission{istart}; % since you are adding behaviors previous to this index, the index will always equal the starting i
			add_behavior(bstruct,(istart-numtomove-numtoshift-ishift));
		end
		for ii=1:numtomove,
			mission(istart+1) = [];
		end
	else
		if index <= 1, return, end
		if index >= length(mission), return, end
		if numtoshift == 0, numtoshift = 1; end
		%if index+numtomove+numtoshift >= length(mission), return, end
		istart = index;
		ishift = 0;
		for ii=0:numtomove-1,
			bstruct = mission{istart + ii};
			add_behavior(bstruct,(istart+numtomove+numtoshift+ishift+ii));
		end
		for ii=1:numtomove,
			mission(istart) = [];
		end
	end
end
if tindexflip < length(headers),
	if (headers(tindexflip+1)==(hindex+numtomove+1) | headers(tindexflip+1)==(hindex+1)),
		% need to jump a group, not just index;
		tmp = gpslegs(tindex+inc);
		gpslegs(tindex+inc) = gpslegs(tindex);
		gpslegs(tindex) = tmp;
		getGpsLegs('clear',0);
		getGpsLegs('set',gpslegs);
	end
end

update_behavior_list(handles)
% get the new set
headers = checkBehaviorIndex('headers',handles,0);
% find position
hposition = headers(tindexflip);
if numtoshift == 1,
	set(handles.listbox1,'Value',hposition);
else
	set(handles.listbox1,'Value',hposition+1);
end
display_Callback(h, eventdata, handles, varargin)

% where are you moving it? is the next index a header too? (collapsed)
% if not, just move group down one. if so, move group down the whole group.
catch, errorbox('move_down_header failed'), end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = block_button_Callback(h, eventdata, handles, varargin)
	global mission
index1 = getBehaviorIndex(handles);
if isempty(index1), return, end
bstruct = mission{index1};
index2 = get(handles.listbox2,'Value');
if isempty(index2), return, end
fields = fieldnames(bstruct);
blocks = '';
if strcmp(fields{index2},'speedblock'),
	modestr = 'speedmode';
	blocks = strvcat(blocks,'rpm');
	blocks = strvcat(blocks,'speed');
elseif strcmp(fields{index2},'verticalblock'),
	modestr = 'verticalmode';
	blocks = strvcat(blocks,'depth');
	blocks = strvcat(blocks,'pitch');
	blocks = strvcat(blocks,'elevator');
    blocks = strvcat(blocks,'altitude');
elseif strcmp(fields{index2},'horizontalblock'),
	modestr = 'horizontalmode';
	blocks = strvcat(blocks,'rudder');
	blocks = strvcat(blocks,'heading');
else
	uiwait(msgbox('Please select a block first','modal'))
	return
end
[s,v] = listdlg('PromptString','Select a block:',...
	'SelectionMode','single','ListString',blocks);
if v == 0, return, end
blk = deblank(blocks(s,:));
mission{index1} = rmfield(mission{index1},fields{index2});
mission{index1} = setfield(mission{index1},modestr,blk);
mission{index1} = setfield(mission{index1},blk,[]);
display_Callback(h, eventdata, handles, varargin)
set(handles.listbox2,'Value',length(fields)+1);
text_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = reset_button_Callback(h, eventdata, handles, varargin)
	global mission
index = getBehaviorIndex(handles);
if isempty(index), return, end
[bdefault,bnames] = behaviordefaults;
bstruct = mission{index};
button=lower(questdlg(['Are you sure you want to reset ' bstruct.name ' to default values?'], ...
	'Confirm Reset','No'));
if strcmp(button,'no') | strcmp(button,'cancel'), return, end

if index == 1,
	bi = findin(bdefault,'name','worksite');
	mission{index} = bdefault{bi};
	mission{index}.name = 'untitled.mis';
	mission{index}.author = '*';
else
	bi = findin(bdefault,'name',bstruct.name);
	mission{index} = bdefault{bi};
end
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = add_field_button_Callback(h, eventdata, handles, varargin)
	global mission
index = getBehaviorIndex(handles);
if isempty(index) | index > length(mission), return, end
prompt = {'Field:','Value:'};
title = ['Add field to ' mission{index}.name];
defans = {'',''};
response = inputdlg(prompt,title,1,defans);
if length(response) ~= 2 | length(response{1}) < 1, return, end
value = mynum2str(response{2});
for i=1:length(value),
	if ~isletter(value) & ~strcmp(value,'*'),
		value = str2num(value);
		break
	end
end
mission{index} = setfield(mission{index},response{1},value);
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = remove_field_button_Callback(h, eventdata, handles, varargin)
	global mission
index1 = getBehaviorIndex(handles);
if isempty(index1) | index1 > length(mission), return, end
index2 = get(handles.listbox2,'Value');
if index1 <= 1, return, end
if isempty(index2), return, end
vars = get(handles.listbox2,'String');
if strcmp(vars{index2},'name'), return, end
field = [mission{index1}.name '.' vars{index2}];
button=lower(questdlg(['Are you sure you want to delete ' field '?'], ...
	'Confirm Remove Field','No'));
if strcmp(button,'no') | strcmp(button,'cancel'), return, end
mission{index1} = rmfield(mission{index1},vars{index2});
display_Callback(h, eventdata, handles, varargin)
	

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = edit_value_Callback(h, eventdata, handles, varargin)
	global mission
[isheader, hindex, hnums] = checkHeaderIndex(handles,0);
if isheader > 0, return, end
index1 = getBehaviorIndex(handles);
if isempty(index1) | index1 > length(mission), return, end
index2 = get(handles.listbox2,'Value');
if isempty(index2), return, end
vars = get(handles.listbox2,'String');
oldvalue = getfield(mission{index1},vars{index2});
value = get(handles.edit_text,'String');
if ~ischar(oldvalue) & ischar(value), value = str2num(value); end
if ischar(oldvalue) & ~ischar(value), value = mynum2str(value); end
mission{index1} = setfield(mission{index1},vars{index2},value);
display_Callback(h, eventdata, handles, varargin)
if index2 < length(vars),
	set(handles.listbox2,'Value',index2+1)
	set(handles.listbox3,'Value',index2+1)
end
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = check_clear_button_Callback(h, eventdata, handles, varargin)
button = questdlg('Do you want to save this mission?');
if strcmp(button,'Yes'),
	save_button_Callback(h, eventdata, handles, varargin)
elseif strcmp(button,'No'),
	clear_button_Callback(h, eventdata, handles, varargin)
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = clear_button_Callback(h, eventdata, handles, varargin)
	global mission, global missionFile, global sonarType, global currentGeoid,
	global referenceLines, global mapData, global mapColor, global mapInfo,
	global auvMarks

mission = [];
missionFile = [];
sonarType = [];
currentGeoid = [];
referenceLines = [];
auvMarks = [];
clear getLegs;
clear getGpsLegs
%mapData = [];
%mapColor = [];
%mapInfo = [];
clearGui(handles)
toggle_buttons(handles,'off')
set(handles.text1,'String','Behavior Stack')
display_Callback(h, eventdata, handles, varargin)

	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = work_site_Callback(h, eventdata, handles, varargin)
	global mission
ws = readMissionFile;
if isempty(ws), return, end
if ~isfield(ws{1},'utmzone'),
	uiwait(msgbox('Please select a worksite.cfg file','modal'))
	return
end
mission{1} = mergestructs(mission{1},ws{1});
set(handles.listbox1,'Value',1)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = cvtUnits_button_Callback(h, eventdata, handles, varargin)
	global mission, global geoUnits
str = get(handles.cvtUnits_button,'String');
if strcmp(geoUnits,'geo'),
	try,
		pause(0.1), set(gcbf,'Pointer','watch')
		cvt2utm
		geoUnits = 'utm';
		str = 'To Geo';
	catch, errorbox, end
	set(gcbf,'Pointer','arrow')
elseif strcmp(geoUnits,'utm'),
	try,	
		pause(0.1), set(gcbf,'Pointer','watch')
		if cvt2geo,
			geoUnits = 'geo';
			str = 'To UTM';
		end
	catch, errorbox, end
	set(gcbf,'Pointer','arrow')
end
set(handles.cvtUnits_button,'String',str)
display_Callback(h, eventdata, handles, varargin)	


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function def = getDefault(bstruct)
def = [];
[bdefaults,bnames] = behaviorDefaults;
name = getBehaviorName(bstruct);
index = indexof(bnames,name);
if ~index, return, end
def = bdefaults{index};


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bstruct = removeDefaults(bstruct)
def = getDefault(bstruct);
if isempty(def), return, end
fields = fieldnames(def);
values = mystruct2cell(def);
for i=1:length(fields),
	if ~isempty(values{i}) & isfield(bstruct,fields{i}) & ~strcmp(fields{i},'name'),
		if compare(getfield(bstruct,fields{i}),values{i})
			bstruct = rmfield(bstruct,fields{i});
		end
	end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bstruct = addDefaults(bstruct)
def = getDefault(bstruct);
if isempty(def), return, end
fields = fieldnames(def);
values = mystruct2cell(def);
for i=1:length(fields),
	if ~strcmp(fields{i},'name') & ~isfield(bstruct,fields{i})
		bstruct = setfield(bstruct,fields{i},values{i});
	end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = hide_defaults_Callback(h, eventdata, handles, varargin)
	global mission
if ~get(handles.hide_defaults,'Value'),
	index = getBehaviorIndex(handles);
	if ~isempty(index) & index > 1,
		if length(index) > 1, index = index(1); end
		mission{index} = addDefaults(mission{index});
	end
end
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = select_button_Callback(h, eventdata, handles, varargin)
	global mission
[isheader,hindex,hnums] = checkHeaderIndex(handles,0);
if isheader >=1, return, end
index = getBehaviorIndex(handles);
if ((length(index) > 1) | isempty(index)), return, end
vars = get(handles.listbox1,'String');
if index == 1,
	set(handles.listbox1,'Value',1:size(vars,1))
else
	[first1,alli] = indexof(vars,mission{index}.name);
	set(handles.listbox1,'Value',alli)
end
display_Callback(h,eventdata,handles,varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = cd_Callback(h, eventdata, handles, varargin)
evalin('base','cd(fileDlg(cd,[],''dirs'',cd))');
set(handles.directory_box,'String',pwd)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = sequence_radio_Callback(h, eventdata, handles, varargin)
if ~get(handles.layers_radio,'Value'),
	set(handles.sequence_radio,'Value',1)
	return, 
end  % already sequence
index = getBehaviorIndex(handles);
set(handles.sequence_radio,'Value',1)
set(handles.layers_radio,'Value',0)
%set(handles.listbox1,'Value',index);
%setBehaviorIndex(handles,index);
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function varargout = layers_radio_Callback(h, eventdata, handles, varargin)
if ~get(handles.sequence_radio,'Value'),
	set(handles.layers_radio,'Value',1)
	return, 
end  % already layers
index = getBehaviorIndex(handles);
set(handles.layers_radio,'Value',1)
set(handles.sequence_radio,'Value',0)
%set(handles.listbox1,'Value',index);
%setBehaviorIndex(handles,index);
update_behavior_list(handles)
display_Callback(h, eventdata, handles, varargin)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [isgrouped] = checkBehaviorGrouped(handles,index)
try,
global numGroupBehaviors
isgrouped = 0;
 % this function works in display space
if ~get(handles.group_checkbox,'Value'), return, end

if index == 0,
	index = get(handles.listbox1,'Value');
	if length(index) > 1, index = index(1); end
end
[isheader,hindex,hnums] = checkHeaderIndex(handles,index);
if isheader==0,
	if ~get(handles.group_checkbox,'UserData'),
		if get(handles.sequence_radio,'Value'),
			numbshowing = numGroupBehaviors;
		else
			numbshowing = fliplr(numGroupBehaviors);
		end
	else
		numbshowing = zeros(1,length(numGroupBehaviors));
	end
	headers = checkBehaviorIndex('headers',handles,0);
	numshift = find(headers>index);
	%if get(handles.group_checkbox,'UserData'), % collapsed
		if length(numshift) == length(numbshowing),
			% index lies before headers - not grouped
			isgrouped = 0;
			return;
		else
			initdisp = headers(1)-1; % number of behaviors before grouping starts
			if (index <= initdisp), isgrouped = 0;
			else
				numshift2 = find(headers<index);
				ngroups = length(numshift2);
				if (index <= (initdisp + numshift2(ngroups) + sum(numbshowing(1:ngroups)))),
					isgrouped = 1;
				end
			end
			return;

		end
	
		%if sum(numbshowing(1:length(numshift)))
	
end
catch, errorbox('checkBehaviorGrouped failed'), end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [bindex,index] = getSelectBehaviorIndex(handles,index)
	global mission, global numGroupBehaviors
% gets the mission index of the behavior immediately following the current header. if not header, same as getBehaviorIndex
try,
bindex = index;
if isempty(mission), return, end
if index==0, index = get(handles.listbox1,'Value'); end
[isheader,hindex,hnums] = checkHeaderIndex(handles,index);
if isheader>=1,
    if isempty(hnums), hnums = 1; end
    for ii=1:length(hnums),
    	currhindex = hindex(hnums(ii));
	if ~get(handles.group_checkbox,'UserData'), % expanded
		index = checkBehaviorIndex('getmissionindex',handles,currhindex+1);
	else 	
		% collapsed - need to find index as if it were expanded
		% [hindex] = getNewHeaderIndex(handles, hindex, 1)
		headers = checkBehaviorIndex('headers',handles,0);
		numshift = length(find(headers < currhindex));
		tindex = getHeaderLegNum(handles, currhindex, 1);
		inc = 0;
		for ii=1:numshift,
			inc = inc + numGroupBehaviors(ii);
		end

		% index as if expanded:
		index = currhindex + inc + 1;
		
		% now find corresponding mission index
		% just subtract the number of headers?
		index = index - (numshift + 1); % (+1: also need to subtract current header, as well as any that came before)
	end
    end
    bindex = index;
    if isempty(index), return, end
    if get(handles.sequence_radio,'Value') & bindex > 1,
    	bindex = length(mission)-bindex+2;
    end
else
	[bindex,index] = getBehaviorIndex(handles);
end


catch, errorbox('getSelectBehaviorIndex failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [bindex,index] = getBehaviorIndex(handles)
	global mission
index = get(handles.listbox1,'Value');
index = checkBehaviorIndex('getmissionindex',handles,index);
bindex = index;
if isempty(index), return, end
for ii=1:length(bindex),
	if get(handles.sequence_radio,'Value') & bindex(ii) > 1,
		bindex(ii) = length(mission)-bindex(ii)+2;
	end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function setBehaviorIndex(handles,index)
	global mission
if isempty(index), return, end
if get(handles.sequence_radio,'Value') & index > 1,
	index = length(mission)-index+2;
end
index = checkBehaviorIndex('getdisplayindex',handles,index);
if isempty(index), index = 1; end
set(handles.listbox1,'Value',index);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function group_behaviors_Callback(h, eventdata, handles, varargin)

% need to revert checkbox till we get the index, then put it back to selected state
set(handles.group_checkbox,'Value',~get(handles.group_checkbox,'Value'))
index = getSelectBehaviorIndex(handles,0);
if isempty(index) | ~index, return, end
set(handles.group_checkbox,'Value',~get(handles.group_checkbox,'Value'))
update_behavior_list(handles)
setBehaviorIndex(handles,index);
display_Callback(h, eventdata, handles, varargin)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [isheader,hindex,hnums] = checkHeaderIndex(handles,index)
% checks if current index is a header, if so, also returns that index
try,
isheader = 0;
hindex = [];
hnums = [];
if ~get(handles.group_checkbox,'Value'), return, end
% need display index, not mission index
if index==0, index = get(handles.listbox1,'Value'); end
if isempty(index), return, end
headers = checkBehaviorIndex('headers',handles,0);
if ~isempty(headers),
	for ii=1:length(index),
		if ~isempty(find(headers == index(ii))),
			isheader(ii) = 1;
			hindex(ii) = index(ii);
			%get(handles.group_checkbox,'UserData')
		end
	end
	if length(isheader) > 1, 
		hnums = find(isheader);
		if isempty(hnums), isheader = 0; 
		elseif length(hnums) ~= length(isheader),
			isheader = 2; % selection includes non-headers
		else
			isheader = 1; 
		end
	end
end

catch, errorbox('checkHeaderIndex failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [newhindex] = getNewHeaderIndex(handles, hindex, expand)
	global mission, global numGroupBehaviors
% convert header indices when switch between expanded and contracted views
newhindex = hindex;

headerindex = checkBehaviorIndex('headers',handles,0);
numshift = length(find(headerindex < hindex));
if get(handles.sequence_radio,'Value'),
	numbehaviors = numGroupBehaviors;
else
	numbehaviors = fliplr(numGroupBehaviors);
end

if expand,
	newhindex = hindex + sum(numbehaviors(1:numshift));
else
	newhindex = hindex - sum(numbehaviors(1:numshift));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [tnum] = getHeaderLegNum(handles, hindex, seq)
% [tnum] = getHeaderLegNum(handles, hindex, seq)
% if seq = 1, give leg number according to display ('trackline 3')
% if seq = 0, give leg number according to mission{}
try,
	headers = checkBehaviorIndex('headers',handles,0);
	position = find(headers == hindex);
	% if layers, tl is backwards from position in header list
	if seq,
		if ~get(handles.sequence_radio,'Value'),
			position = length(headers) - (position - 1);
		end
	else
		if get(handles.sequence_radio,'Value'),
			position = length(headers) - (position - 1);
		end
	end
	tnum = position;
catch, errorbox('getHeaderLegNum failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function display_header(handles, hindex)
try,
	global mission, global numGroupBehaviors
set(handles.edit_text,'String','')
set(handles.behavior_index,'String','')
set(handles.text5,'String','')
set(handles.text6,'String','')
set(handles.text7,'String','')
set(handles.listbox2,'String','')
set(handles.listbox3,'String','')
set(handles.listbox2,'Value',1);
set(handles.listbox3,'Value',1);

% now set the header text, see display_Callback

	trackinfo = [];
% get the start of the mission index for this header
	headerindex = checkBehaviorIndex('headers',handles,0);
	numshift = length(find(headerindex < hindex));
	mindex = hindex - numshift;
	if get(handles.group_checkbox,'UserData'),
		% collapsed
		mindex = mindex + (sum(numGroupBehaviors(1:numshift)));
	end
	
	tindex = getHeaderLegNum(handles, hindex, 1);
	
	numbehaviors = numGroupBehaviors;
	gpssublegs = getGpsLegs('get');
	
	bindex = mindex;
	if get(handles.sequence_radio,'Value') & bindex > 1,
		bindex = length(mission)-bindex+2;
	end
	if get(handles.sequence_radio,'Value'),
		if (gpssublegs(tindex) > 1), behpergps = numbehaviors(tindex)/gpssublegs(tindex); 
		else, behpergps = numbehaviors(tindex); end
		if (gpssublegs(tindex) < 1), gpssublegs(tindex) = 1; end
		iwaypoint = 0;
		iendtrack = 5 + (gpssublegs(tindex)-1)*behpergps;
		imidtrack = 3 + (gpssublegs(tindex)-1)*behpergps;
	else
		iwaypoint = numbehaviors(tindex)-1;
		if (gpssublegs(tindex)>0),
			iendtrack = 2;
			imidtrack = 4;
		else
			iendtrack = 0;
			imidtrack = 2;
		end
	end
	
	if get(handles.sequence_radio,'Value'),
		endindex = bindex - (numbehaviors(tindex) - 1);
		for ii=bindex:-1:endindex,
			bstruct = mission{ii};
			name = lower(bstruct.name);
			% waypoint first, end tl 6
			if ((bindex - ii) == iwaypoint), 		% first waypoint
				[trackinfo] = getXY(bstruct,trackinfo,'init');
				if isfield(bstruct,'depth'), trackinfo.depth = bstruct.depth; end
			else
				if ((bindex-ii) == iendtrack),
					[trackinfo] = getXY(bstruct,trackinfo,'end');
				elseif ((bindex-ii) == imidtrack), % middle trackline
					if isfield(bstruct,'duration'), trackinfo.duration = bstruct.duration; end
					if isfield(bstruct,'rpm'), trackinfo.rpm = bstruct.rpm; end
				end
			end
		end
	else % waypoint last, end tl 3
		endindex = bindex + (numbehaviors(tindex) - 1);
		for ii=bindex:endindex, % number of trackline behaviors
			bstruct = mission{ii};
			name = lower(bstruct.name);
			if ((ii-bindex) == iwaypoint),
				[trackinfo] = getXY(bstruct,trackinfo,'init');
				if isfield(bstruct,'depth'), trackinfo.depth = bstruct.depth; end
			else
				if ((ii-bindex) == iendtrack),
					[trackinfo] = getXY(bstruct,trackinfo,'end');
				elseif ((ii-bindex) == imidtrack), % middle trackline
					if isfield(bstruct,'duration'), trackinfo.duration = bstruct.duration; end
					if isfield(bstruct,'rpm'), trackinfo.rpm = bstruct.rpm; end
				end
			end
		end
	end

	if ~isempty(trackinfo),
	attributes = fieldnames(trackinfo);
	values = mystruct2cell(trackinfo);
	index2 = get(handles.listbox2,'Value');
	if index2 > length(values), index2 = 1; end
	set(handles.listbox2,'Value',index2)
	set(handles.listbox3,'Value',index2)
	set(handles.listbox2,'String',attributes)
	set(handles.listbox3,'String',values)
	%text_Callback(h,eventdata,handles,varargin);
	end
catch, errorbox('display_header failed'), end

%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [trackinfo] = getXY(bstruct,trackinfo,pos)

if strcmp(pos,'init'),
	if isfield(bstruct,'latitude') & isfield(bstruct,'longitude'),
		trackinfo.initiallon = bstruct.longitude;
		trackinfo.initiallat = bstruct.latitude;
	elseif isfield(bstruct,'northing') & isfield(bstruct,'easting'),
		trackinfo.initiale = bstruct.easting;
		trackinfo.initialn = bstruct.northing;
	end
else
	if isfield(bstruct,'latitude') & isfield(bstruct,'longitude'),
		trackinfo.longitude = bstruct.longitude;
		trackinfo.latitude = bstruct.latitude;
	elseif isfield(bstruct,'northing') & isfield(bstruct,'easting'),
		trackinfo.easting = bstruct.easting;
		trackinfo.northing = bstruct.northing;
	end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function quit_Callback(h, eventdata, handles, varargin)
answer = questdlg('Do you really want to exit?');
if strcmp(answer,'Yes'), closereq, end
if strcmp(answer,'Cancel'),
	button = questdlg('Then why did you hit the exit button?','','Oops', ...
		'I''m Bored',[]);
	if strcmp(button,'I''m Bored'),
		s = load('cookies.mat');
		num = ceil(rand*length(s.lines));
		answer = ' ';
		while ~strcmp(answer,'Stop The Madness!'),
			num = mod(num,length(s.lines))+1;
			str = s.lines(num,:);
			answer = questdlg(str,'','Stop The Madness!','More, Please!',[]);	
		end
	end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function deg2dm_button_Callback(h, eventdata, handles, varargin)
	global mission
if ~isempty(mission),
	index1 = getBehaviorIndex(handles);
	if isempty(index1), return, end
	bstruct = mission{index1};
	index2 = get(handles.listbox2,'Value');
	if isempty(index2), return, end
	set(handles.listbox3,'Value',index2)
	vars = get(handles.listbox2,'String');
	field = lower(vars{index2});
	if ~isempty(findstr(field,'lat')),
		defans{1} = mynum2str(getfield(mission{index1},field));
		islat = 1;
	elseif ~isempty(findstr(field,'lon')),
		defans{1} = mynum2str(getfield(mission{index1},field));
		islat = 0;	
	else
		defans{1} = '';
		islat = -1;
	end
else
	defans{1} = '';
	islat = -1;
end
prompt{1} = 'Enter decimal degrees:';
title = 'Convert Decimal Degrees';
answer = inputdlg(prompt,title,1,defans);
if isempty(answer), return, end
if islat == 1,
	str = lat2str(str2num(answer{1}));
elseif islat == 0,
	str = lon2str(str2num(answer{1}));
else
	in = str2num(answer{1});
	deg = fix(in);
	minutes = 60*(abs(in)-abs(deg));
	str = [int2str(deg) ' degrees, ' mynum2str(minutes) ' minutes'];
end
str = [answer{1} ' degrees is ' str];
uiwait(msgbox(str,title,'modal'));


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function dm2deg_button_Callback(h, eventdata, handles, varargin)
prompt{1} = 'Enter degrees, negative for West or South:';
prompt{2} = 'Enter minutes:';
title = 'Convert Degrees, Decimal Minutes';
answer = inputdlg(prompt,title,1);
if isempty(answer), return, end
deg = str2num(answer{1});
minutes = str2num(answer{2});
result = abs(deg) + minutes/60;
if deg < 0, result = -result; end

str = [answer{1} ' degrees, ' answer{2} ' minutes is ' mynum2str(result) ' degrees'];
uiwait(msgbox(str,title,'modal'));