-- 这是聚光灯控制脚本，用lua 5.2.x语言编写。聚光灯介绍形式是枫传网络独创的软件介绍方式。通过将软件界面雾化为背景，并用聚光灯突显要介绍的部分，配合文字说明，对软件进行介绍。您可以按照提示修改此脚本。
-- 下面为文件信息，除CodePage外，其它项目请不要修改。
Application = "GTalkabout"
Version = "1.1"
ScriptType = "tutorial"
CodePage = 936	-- 简体中文，如果您将此脚本翻译为其他语种，请修改为该语种对应的代码页，否则，请不要修改。
Example = "function_map"

-- 下面为介绍文字，是markdown格式文本。您可以将其翻译为其它语种或进行修改，请不要修改圆括号内的文字。

FunctionMap_text = [[
1.1.3~1.1.5版新功能
===
极客讨论器可以自动分析源代码并创建函数地图，展示函数间的调用关系。  
函数地图是一种展示函数间调用和被调用关系的图。它不是简单的一张图片，而是和源代码联动的界面，您可以通过源代码定位地图上的函数节点，反之也可以通过地图上的函数节点定位源代码。  
它还可以和内置版本控制工具协同工作，展示您的源代码里的每个函数的修改状态，一个函数是新增，删除，修改，还是和工作副本一致，通过节点上的状态图标加以展示。  
![函数地图](function_map.png)

目前共支持C/C++/Java/C#/Objective-C/Python六种开发语言的函数地图，很快会支持更多的语言。  
我们提供了一个向导为您介绍函数地图的使用方法。请[点击开始](start)

[关闭向导](cancel_auto_load)
]]

RecentConfig_text = [[
选择演示例子
===
以下四个配置是用不同语言开发的益智游戏《俄罗斯方块》，请选择您所熟悉语言的版本。*例子源代码来自互联网，版权归原作者*  
[上一步](index)
]]

GTalkabout_Ungray_text = [[
创建函数地图
===
源代码已经打开了，请选择**函数地图**标签页，并点击 ![生成按钮](functionmap_build_cn.bmp)，出来提示消息后再点击“确定”，即开始创建函数地图...
]]

GTalkabout_FunctionMap_text = [[
函数地图介绍
===
函数地图已经创建，您可以拖动滚动条查看它的全貌。下面是图例说明：  
![调用/被调用图例](call_caller.png) ：函数节点通过箭头指向它调用的函数节点，如图表示main函数调用了SayHello函数;  
![未修改状态图标](normal.png)：此函数节点的subversion状态为normal，它没有被修改;  
![修改状态图标](modified.png)：此函数节点的subversion状态为modified，它被修改了;  
![增加状态图标](added.png)：此函数节点的subversion状态为added/unversioned，它是新增函数;  
![删除状态图标](deleted.png)：此函数节点的subversion状态为deleted/missing，它是删除函数。

*一旦函数地图创建后，它会追踪您代码的修改，并更新函数节点的状态图标。但是它并不会更新地图的结构，也就是增加/删除函数节点，或者增加/删除表示调用关系的箭头。您可以随时点击“重新生成”按钮重建函数地图。*  
[下一步 1.1.4版新功能——旅行模式介绍](ver1_1_4)
]]

Version1_1_4_text = [[
旅行模式介绍
===
当 ![地图按钮](functionmap_travelling_mode.bmp) 为按下状态（目前是按下状态）即是旅行模式。请双击一个函数节点……
]]

FunctionNode_text = [[
旅行模式介绍
===
打开了此函数的代码，带有背景色突出显示的是由它调用的函数。请选中带背景色的代码……
]]

FunctionCode_text = [[
旅行模式介绍
===
请选中带背景色的代码……
]]

FunctionGoto_text = [[
旅行模式介绍
===
![前往按钮](functionmap_goto_cn.bmp) 已经可用，请点击它……
]]

Caller_Callee_text = [[
旅行模式介绍
===
可以看到打开了被调用函数的代码，而调用关系记录在消息板中，并且是超链接形式，方便您随时回到调用函数，和调用位置。

[下一步 1.1.5版新功能——消息路标介绍](ver1_1_5)
]]

Version1_1_5_text = [[
消息路标介绍
===
极客讨论器的消息可以批注源代码，如果被批注代码在某函数内，就会在这个函数节点上建立一个消息路标。例如：  
![带路标的函数节点](roadsign.png)：get\_current\_micros函数节点上有一个路标图标，表示至少有一条消息指向这个函数内的代码。  
消息路标可以帮您查找这个函数的批注消息，还可以快速定位函数节点；  
更重要的功能是，您可以在查看其它代码时，快速判断这段代码是否和带路标的函数有调用关系，以及查找调用链。

当 ![路标按钮](functionmap_roadsign.bmp) 为按下状态（目前是按下状态），消息自动为被批注代码所在的函数建立路标；  
当 ![闪光路标按钮](functionmap_passed_roadsign.bmp) 为按下状态（目前是按下状态），查找路标函数和选中代码之间的调用链。

现在演示怎么建立消息路标。要建立和源代码关联的批注消息，请按下 ![钉子按钮](link_tool_button.bmp)……
]]

Click_Link_text = [[
消息路标介绍
===
这样，创建的消息就是<font color=#f00>批注消息</font>，将和选中源代码关联。我们以刚才自动记录的调用位置为例，请点击右上方消息板“调用”（calls）后的链接……
]]

Click_Callee_text = [[
消息路标介绍
===
请点击消息板“调用”后的链接……
]]

Compose_Message_text = [[
消息路标介绍
===
这时您可以编辑消息说明此处为什么要调用，调用参数，对程序的影响等等。也可以什么都不写，点击 ![记录按钮](record_cn.bmp)……
]]

ThankYou_text = [[
消息路标介绍
===
在函数地图出现了一个路标，单击它可以找到这个函数的批注消息，双击它可以定位函数节点。  
关闭向导后，您可以查看其它代码和此路标标注的函数相互间是否有调用关系，以及找到调用链。  
可以用同样的方法建立多个路标，哪一段代码和什么功能相关，就可以很快理解了。

对于GitHub上的开源项目，我们提供了一个笔记类极客网站[程序员记](http://www.progbbs.com)在线保存和分享消息。  
在这里，您可以批注一段源代码，其他人也可以使用您的批注帮助他们理解源代码，事半功倍；  
或者，向其他人求助，如果您是开源项目的作者，也可以发送TODO/FixMe消息请求他人的协助。  
这些批注消息可以用来建立消息路标。

*消息路标是用批注消息建立起来的，而批注消息是关联到版本库内的代码，并在提取时映射到可能发生修改的代码上，  
所以不用担心您记录或者阅读的消息路标因为代码修改而失效。*

[关闭向导](cancel_auto_load)
]]

FunctionMap_TabPage_controls = { {"control_tab", 1}, {"function_map_travelling", 0}, {"function_map_roadsign", 0}, {"function_map_passed_roadsign", 0} }
FunctionMap_TabPage_and_ResEdit_Panel_controls = { {"resedit_panel", 1}, {"control_tab", 1}, {"function_map_travelling", 0}, {"function_map_roadsign", 0}, {"function_map_passed_roadsign", 0} }

-- 下面为聚光灯流程控制，请不要修改！
function ControlValueIterator(ControlTable)
	local iIndex = 0

	return function()
		iIndex = iIndex + 1;
		local ControlValue = ControlTable[iIndex];

		if type(ControlValue) == "string" then
			return ControlValue, "";
		elseif type(ControlValue) == "table" then
			local Control, Value = ControlValue[1], ControlValue[2];

			if type(Control) == "string" then
				if type(Value) == "string" then
					return Control, Value;
				else
					return Control, "";
				end
			else
				return nil;
			end
		else
			return nil;
		end
	end
end

function CopyIterator(Iter, ControlTable)
	local Iter2 = Iter;
	local Iter2_upvalue = 1;

	function Iter2()
		local _, Origin = debug.getupvalue(Iter, 1);
		debug.setupvalue(Iter, 1, Iter2_upvalue);
		local Result = Iter()
		_, Iter2_upvalue = debug.getupvalue(Iter, 1);
		debug.setupvalue(Iter, 1, Origin);
		return Result;
	end
	return Iter2;
end

function ChangeSpotlights_recent_config(Iter, ControlTable)
	return { {"recent_config", 1} }, RecentConfig_text;
end

function ChangeSpotlights_gtalkabout_ungray(Iter, ControlTable)
	return FunctionMap_TabPage_controls, GTalkabout_Ungray_text;
end

function ChangeSpotlights_function_map_building(Iter, ControlTable)
	return FunctionMap_TabPage_controls, GTalkabout_Ungray_text;
end

function ChangeSpotlights_function_map_rendering(Iter, ControlTable)
	return FunctionMap_TabPage_controls, GTalkabout_Ungray_text;
end

function ChangeSpotlights_function_map_ready(Iter, ControlTable)
	return FunctionMap_TabPage_controls, GTalkabout_FunctionMap_text;
end

function ChangeSpotlights(ControlTable)
	local Iter = ControlValueIterator(ControlTable);
	local Control, Value = Iter();

	if Control == "index" then
		return {}, FunctionMap_text;
	elseif Control == "start" or Control == "recent_config" then
		return ChangeSpotlights_recent_config(Iter, ControlTable);
	elseif Control == "ver1_1_4" then
		return FunctionMap_TabPage_and_ResEdit_Panel_controls, Version1_1_4_text;
	elseif Control == "ver1_1_5" then
		return { {"control_tab", 0}, {"im_tab", 0}, {"instant_link", 1} }, Version1_1_5_text;
	elseif Control == "gray" and Value == "error" then
		return {}, "";
	elseif (Control == "gray" and Value == "false") or (Control == "return") then
		return ChangeSpotlights_gtalkabout_ungray(Iter, ControlTable);
	elseif Control == "function_map_build" then
		if Value == "building" then
			return ChangeSpotlights_function_map_building(Iter, ControlTable);
		elseif Value == "rendering" then
			return ChangeSpotlights_function_map_rendering(Iter, ControlTable);
		else
			return ChangeSpotlights_function_map_ready(Iter, ControlTable);
		end
	elseif Control == "function_map_goto" then
		if Value == "enabled" then
			return FunctionMap_TabPage_and_ResEdit_Panel_controls, FunctionGoto_text;
		elseif Value == "disabled" then
			return FunctionMap_TabPage_and_ResEdit_Panel_controls, FunctionCode_text;
		elseif Value == "dblclk" then
			return FunctionMap_TabPage_and_ResEdit_Panel_controls, FunctionNode_text;
		elseif string.match(Value, "%d+->%d+:%d+") == Value then
			return { {"control_tab", 0}, {"resedit_panel", 0}, {"im_tab", 1}, {"instant_link", 0}, {"instant_patch", 0} }, Compose_Message_text;
		elseif string.match(Value, "%d+") == Value then
			return { {"control_tab", 0}, {"resedit_panel", 0}, {"im_tab", 1}, {"instant_link", 0}, {"instant_patch", 0} }, Click_Callee_text;
		end
		return { {"control_tab", 0}, {"resedit_panel", 0}, {"im_tab", 0} }, Caller_Callee_text;
	elseif Control == "instant_link" and Value == "true" then
		return { {"control_tab", 0}, {"resedit_panel", 0}, {"im_tab", 1}, {"instant_link", 0}, {"instant_patch", 0} }, Click_Link_text;
	elseif Control == "instant_record" then
		return { {"control_tab", 1}, {"im_tab", 1} }, ThankYou_text;
	elseif Control == "close" or Control == "cancel_auto_load" then
		return {}, "";
	end
end

AutoLoad = 0