module DarkHall
	class TownMenuPhase < Phase
		def on_enter(from)
			super
			$section = TOWN
			
			
			
			#@week_window = TextWindow.new.make_surface(100)
			#@week_window.update(_("第%{w}週").evaluate(:w => GS.week))
			#@week_window.dock_beside(PARTY_WINDOW, :top)
			
			DESCRIPTION_WINDOW.update('').set_position(:center, 8)
			
			@picture_window = PictureWindow.new.make_surface('machi+2.png').update
			@picture_window.dock_beside(DESCRIPTION_WINDOW, :bottom)
			
			$windows = [@picture_window, PARTY_WINDOW, CAPTION_WINDOW]
			if GS.game_config.command_description_visible? then
				HELP_WINDOW.make_surface(_('F1～F4: システムメニュー'), 1).update([_('F1～F4: システムメニュー')])
				#HELP_WINDOW.dock_beside(DESCRIPTION_WINDOW, :bottom)
				HELP_WINDOW.dock_beside(PARTY_WINDOW, :top)
				HELP_WINDOW.right = PARTY_WINDOW.right
				HELP_WINDOW.show
				DESCRIPTION_WINDOW.show
			end
			
			
			select_items = SELECT_WINDOW.select_items.clear
			select_items << SelectItem.new(:bar, _("酒場(B)"), SDL::Key::B)
			select_items << SelectItem.new(:inn, _("宿屋(I)"), SDL::Key::I)
			select_items << SelectItem.new(:shop, _("商店街(S)"), SDL::Key::S)
			select_items << SelectItem.new(:guild, _("冒険者ギルド(G)"), SDL::Key::G)
			select_items << SelectItem.new(:hermitage, _("魔道師の穴ぐら(M)"), SDL::Key::M)
			select_items << SelectItem.new(:dungeon, _("迷宮の入り口(D)"), SDL::Key::D)
			select_items << SelectItem.new(:test, _("＊デバッグ用メニュー")) if Game.debug_mode?
			
			


			if GS.party.members.empty? then
				select_items[1].disable
				select_items[2].disable
				select_items[4].disable
			end
			
			if GS.party.members.empty? and GS.dungeon_parties.empty? then
				select_items[5].disable
			end
			
			if GS.members.empty? then
				select_items[0].disable #(_('まず新たな冒険者を登録してください'))
			end
			
			CAPTION_WINDOW.make_surface(200, 1).update(_("街"))
			#.set_position(:center, 80)
			CAPTION_WINDOW.dock_beside(@picture_window, :right)
			CAPTION_WINDOW.top = DESCRIPTION_WINDOW.bottom + 8
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size).update.dock_beside(CAPTION_WINDOW, :bottom)
			SELECT_WINDOW.show
			SELECT_WINDOW.reset_index.warp
			
			on_change
			
			BGM.load(:Town)
			BGM.play(:Town)
		end
		
		def on_change
			case SELECT_WINDOW.current_id
			when :bar
				DESCRIPTION_WINDOW.update _('パーティーの編成、ステータスの確認ができる')
			when :inn
				DESCRIPTION_WINDOW.update _('1週間休息をとり、体力・魔力を回復することができる')
			when :shop
				DESCRIPTION_WINDOW.update _('アイテムの売り買いや、持ち物の識別依頼ができる')
			when :guild
				DESCRIPTION_WINDOW.update _('新しいキャラクターの登録、名前の変更などができる')
			when :hermitage
				DESCRIPTION_WINDOW.update _('呪文の習得や、仲間の蘇生依頼ができる')
			when :dungeon
				DESCRIPTION_WINDOW.update _('冒険の舞台')
			end
		end
		
		def on_select(id)
			
			case id
			when :bar
				#BAR_MENU_WINDOW.show
				#self.hide
				Phase.change(BarMenuPhase.new)
			when :shop
				Phase.change(ShopMenuPhase.new)
			when :inn
				if Game.ask(_("宿屋に泊まって一週間を過ごします。\nよろしいですか？")) then
					Phase.change(InnMenuPhase.new)
				else
					SELECT_WINDOW.warp
				end
			when :guild
				Phase.change(GuildMenuPhase.new)
			when :test
				Phase.change(TestMenuPhase.new)
			when :hermitage
				Phase.change(HermitageMenuPhase.new)
			when :dungeon
				Phase.change(DungeonEntranceMenuPhase.new)
			end
		end
	end
	
	class TestMenuPhase < Phase
		def on_enter(from)
			$windows = [PARTY_WINDOW, CAPTION_WINDOW, WARNING_WINDOW,SELECT_WINDOW]
			select_items = SELECT_WINDOW.select_items.clear
			select_items << SelectItem.new(:character_make, "キャラクター簡易作成")
			select_items << SelectItem.new(:all_spell_learn, "全術習得")
			select_items.last.disable if GS.party.members.empty?
			select_items << SelectItem.new(:levelup, "レベルアップ")
			select_items.last.disable if GS.party.members.empty?
			select_items << SelectItem.new(:cancel, "キャンセル")

			
			CAPTION_WINDOW.make_surface(200, 1).update("テスト用メニュー").set_position(:center, 80)
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size).dock_beside(CAPTION_WINDOW, :bottom)
			SELECT_WINDOW.reset_index.warp
			WARNING_WINDOW.reset(250)
		end
		
		def on_select(id)
			case id
			when :dungeon
				Phase.change(DungeonStartPhase.new)
			when :restart
				Phase.change(RestartAdventurePhase.new)
			when :gold
				SE.coin
				GS.party.members.first.gold += 200
			when :levelup
				GS.party.members.each{|x| x.exp = EXP_TABLE[x.level+1]}
				Game.message("#{GS.party.name}はレベルアップに必要な経験値を得ました\n宿屋で寝るとレベルが上がります")
				
			when :all_spell_learn
				GS.got_spell_ids += DB.spells.map{|x| x.id}
				GS.party.members.each do |member|
					SPELL_ORDER.each do |spell|
						member.spell_learning[spell] = 4
					end
				end
				Game.message("全ての術を習得しました")
			when :character_make
				if (level = Game.number_input('レベルを入力してください', 1, 1..LEVEL_MAX)) then
					classes = [Fighter, HeavyFighter, HeavyFighter, Archer, Magician, Explorer, Prayer, Academian, Grappler]
					
					classes.each do |cls|
						Game.add_default_member(cls, level)
					end
					SE.equip
	
					Game.save(FQ_BIG_CHANGE, "新規キャラクターの簡易作成")
					message("8人のLv#{level}若者キャラクターを自動作成しました")
				end

			when :cancel
				self.on_cancel
			end
			PARTY_WINDOW.update
		end
		
		def on_cancel
			Phase.change(TownMenuPhase.new)
			SELECT_WINDOW.set(:test).warp
			$phase.on_change
		end
	end

	
	class DungeonEntranceMenuPhase < Phase
		def on_enter(from)
			BGM.fade_out
			$windows = [PARTY_WINDOW, CAPTION_WINDOW, DESCRIPTION_WINDOW, WARNING_WINDOW, SELECT_WINDOW]
			select_items = SELECT_WINDOW.select_items.clear
			select_items << SelectItem.new(:dungeon, _("迷宮に入る(E)"), SDL::Key::E)
			select_items.last.description = _("現在のパーティーで迷宮の探索を開始")
			select_items.last.disable(_("探索できるメンバーがいません")) if GS.party.alive_members.empty?
			select_items << SelectItem.new(:restart, _("冒険の再開(R)"), SDL::Key::R)
			if GS.dungeon_parties.empty? then
				select_items.last.disable(_("誰も迷宮の中にいません"))
			end
			select_items.last.description = _("迷宮内にいるパーティーの冒険を再開")
			select_items << SelectItem.new(:cancel, _("戻る"))
			select_items.last.description = _("街に戻る")
			
			#show_command_description

			CAPTION_WINDOW.make_surface(200, 1).update(_("迷宮の入り口")).set_position(:center, 80)
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size).dock_beside(CAPTION_WINDOW, :bottom)
			SELECT_WINDOW.reset_index.warp
			WARNING_WINDOW.reset(240)
			
			on_change
		end
		
		def on_select(id)
			case id
			when :dungeon
				found = GS.party.members.find{|x| x.spell_caster? and x.spells.empty?}
				msg = _("%{member}は呪文を一つも習得していません。\nこのまま迷宮に入ってもよろしいですか？\n（呪文は$c[good]%{hermitage}$cで習得することができます）")
				if not found or Game.ask(msg.evaluate(:member => found.name, :hermitage => _('魔道師のあなぐら'))) then
					Phase.change(DungeonStartPhase.new)
				end
			when :restart
				if GS.party.members.empty? then
					Phase.change(RestartAdventurePhase.new)
				else
					msg = _("迷宮の中にいるパーティーの冒険を再開します\n（%{current_party}は酒場に戻ります）\n\nよろしいですか？")
					if Game.ask(msg.evaluate(:current_party => GS.party.name)) then
						Phase.change(RestartAdventurePhase.new)
						
					end
				end
			when :cancel
				self.on_cancel
			end
			PARTY_WINDOW.update
		end
		
		def on_cancel
			Phase.change(TownMenuPhase.new)
			SELECT_WINDOW.set(:dungeon).warp
		end
		

	end
	
	
	class RestartAdventurePhase < PartySelectPhase
	
		def on_enter(from)
			@waiting_party_id = GS.current_party_id
			super
		end
		
		def information_text
			_("どのパーティーの冒険を再開しますか？")
		end
		
		def showing_windows
			[PARTY_WINDOW, WARNING_WINDOW, INFORMATION_WINDOW, SELECT_WINDOW]
		end
		
		def showing_cancel?
			true
		end
		
		def on_select(id)
			if id == :cancel then
				on_cancel
			else
				# 現パーティーは解散
				GS.bar_member_ids += GS.parties[@waiting_party_id].member_ids
				
				# パーティー変更
				GS.current_party_id = id

				# 選択したパーティーを1番目に順序変更（次のパーティー選択時の利便性のため）
				GS.move_party_to_first(id)
				
				Phase.change(DungeonRestartPhase.new)
			end
		end
		
		def on_cancel
			GS.current_party_id = @waiting_party_id
			Phase.change(DungeonEntranceMenuPhase.new)
			SELECT_WINDOW.set(:restart)
		end
		

	end

	
	
	class BarMenuPhase < Phase

		def on_enter(from)
			super
			$windows = [PARTY_WINDOW, CAPTION_WINDOW, DESCRIPTION_WINDOW, SELECT_WINDOW]
			select_items = SELECT_WINDOW.select_items.clear
			select_items << SelectItem.new(:status, _("ステータス(S)"), SDL::Key::S)
			select_items.last.description = _('冒険者の状態の確認、道具の整理、装備の変更などを行う')
			select_items.last.disable if GS.party.members.empty?
			select_items << SelectItem.new(:join, _("仲間を加える(J)"), SDL::Key::J)
			select_items.last.description = _('酒場にいる冒険者を、パーティーに加える(最大６人)')
			select_items.last.disable if (GS.party.members.size >= 6) || (GS.bar_member_ids.empty?)
			select_items << SelectItem.new(:leave, _("仲間をはずす(L)"), SDL::Key::L)
			select_items.last.description = _('パーティーにいる冒険者を離脱させ、酒場に戻す')
			select_items.last.disable if GS.party.members.empty?
			select_items << SelectItem.new(:order_change, _("並び替え(O)"), SDL::Key::O)
			select_items.last.description = _('パーティーメンバーの順番を並び替える')
			select_items.last.disable if GS.party.members.empty?
			select_items << SelectItem.new(:share, _("お金を山分けする"))
			select_items.last.description = _('パーティーメンバー全員の所持金を山分けする')

			select_items.last.disable if GS.party.members.empty?
			select_items << SelectItem.new(:expert_talk, _("常連の話を聞く(T)"), SDL::Key::T)
			select_items.last.description = _('冒険のヒントなどを教えてもらう')

			select_items << SelectItem.new(:cancel, _("戻る"))
			select_items.last.description = _('街に戻る')
			
			
			CAPTION_WINDOW.make_surface(200, 1).update(_("酒場")).set_position(:center, 80)
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size).dock_beside(CAPTION_WINDOW, :bottom)
			SELECT_WINDOW.reset_index.warp
			
			on_change
		end
		
		def on_select(id)
			super
			case id
			when :join
				Phase.change(BarMemberJoinPhase.new)
			when :leave
			
			
				loop do
					index = Game.member_select(_("だれを？"))
					if index then
						member_id = GS.members.index(GS.party.members[index])
						if member_id && GS.party.leave_member(member_id) then
							GS.bar_member_ids << member_id
							Game.save(FQ_SMALL_CHANGE, "#{GS.members[member_id].name}がパーティーを離脱")
							PARTY_WINDOW.update.regulate_index
						end
					else
						break
					end
				end
				Game.save(FQ_CHANGE, '仲間の離脱')
				Phase.change($phase)
				SELECT_WINDOW.set(:leave)
			when :share
				GS.party.share_gold
			when :order_change
				Phase.change(TownOrderChangePhase.new)
			when :status
				$member_index = Game.member_select(_("だれを？"))
				if $member_index then
					Phase.change(StatusPhase.new)
				else
					SELECT_WINDOW.show.warp
				end
			when :expert_talk
				Phase.change(ExpertTalkPhase.new)
			when :cancel
				Phase.change(TownMenuPhase.new)
			end
		end
		
		def on_cancel
			
			Phase.change(TownMenuPhase.new)
			SELECT_WINDOW.set(:bar).warp
			$phase.on_change
		end
		

		
	end
	
	class ExpertTalkPhase < Phase
		def on_enter(from)
			super
			$windows = [PARTY_WINDOW, CAPTION_WINDOW, SELECT_WINDOW]
			select_items = SELECT_WINDOW.select_items.clear
			select_items << SelectItem.new(:fighter, s_("Adviser|頬に傷のある老戦士"))
			select_items << SelectItem.new(:explorer, s_("Adviser|若い女探検家"))
			select_items << SelectItem.new(:magician, s_("Adviser|ローブを目深に被った術師"))
			select_items << SelectItem.new(:cancel, _("キャンセル"))
			CAPTION_WINDOW.make_surface(240, 1).update(_('常連の話を聞く')).set_position(:center, 100)
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size).dock_beside(CAPTION_WINDOW, :bottom)
			SELECT_WINDOW.reset_index.warp
		end
		
		def on_select(talker)
			case talker
			when :fighter
				message(_("お前たちが俺の助言を望むなら\n戦いの基本をアドバイスしてやろう。\n\nさあ、何が聞きたい？"))
				items = []
				items << SelectItem.new(:formation, s_("Advice|前衛・後衛"))
				items << SelectItem.new(:speed, s_("Advice|行動速度"))
				items << SelectItem.new(:weapon, s_("Advice|武器による攻撃"))
				items << SelectItem.new(:special_weapon, s_("Advice|特殊な武器(弓、杖)"))
				items << SelectItem.new(:damage_type, s_("Advice|攻撃属性"))
				items << SelectItem.new(:armor, s_("Advice|鎧・外套による防御"))
				items << SelectItem.new(:shield, s_("Advice|盾による防御"))
				items << SelectItem.new(:block, s_("Advice|ブロック"))
				items << SelectItem.new(:death, s_("Advice|ダメージによる死亡と蘇生"))
				#items << SelectItem.new(:state, s_("Advice|状態異常"))
				#items << SelectItem.new(:skill, s_("Advice|特技"))
				items << SelectItem.new(:cancel, s_("Advice|話を聞くのを止める"))
				
				self.talk(items) do |id|
					case id
					when :formation
						case GS.party.members.size
						when 0
							forward_number = nil
						when 1..2
							forward_number = 1
						when 3..4
							forward_number = 2
						when 5..6
							forward_number = 3
						end
						msg = _("戦闘では前衛・後衛のどちらに立つかが重要になる。\n何人が前衛になるかは、パーティーの人数次第だ。")
						msg += _("\n\nお前たちの場合なら、前から%{forward}人が前衛に立つことになるな。").evaluate(:forward => forward_number) if forward_number
						message(msg)
						message(_("前衛に立った場合は、敵に剣・斧などを振るうことができるが\n同時に敵からの攻撃を受けることにもなる。\n\n後衛なら、弓や呪文を用いないと攻撃できないが\n逆に攻撃を受ける機会も減る。"))
						message(_("軽戦士や重戦士は前衛に、そのほかは後衛に立つのが基本だ。\n\nとはいえ、前衛の人数が足りなければ\n弓闘士や探検家、術師などが前に出る必要もあるだろう。"))
					when :speed
						message(_("誰が一番早く行動できるかは、基本的に「素早さ」で決まる。\n要するに、動きが素早い奴ほど早く攻撃できるわけだ。\n\n一応、鎧や外套の熟練も少し影響するが\nあまり考えなくてもいいだろう。"))
						message(_("だから敵より早く行動したいなら\n素早さを何らかの方法で上げるといい。\n地道にレベルを上げるほか、呪文や装備の力を借りてもいいだろう。"))
						message(_("ただし、行動の種類によっては\n必ずしも早い奴が行動できるとも限らん。\n\nたとえば「猛襲」「フェイント」は、通常より少し早く発動できる。\n逆に道具を使おうとすれば、行動に移るのが少し遅くなるだろう。"))
						message(_("さらに、$c[em]無条件で先手を取れる行動もある。$c\n\n「身を守る」「ブロック」、それに一部の特技などは\n必ずラウンドの最初に効果が発動するはずだ。\n覚えておくと役に立つかもしれんな。"))
					when :weapon
						message(_("武器は敵を打ち倒すために必要不可欠なもの。\n\nそれゆえに、武器の特性を理解することは重要だ。"))
						message(_("まず、見るべきなのは「武器威力」と「攻撃回数」だ。\nこの二つの数値は、どっちもダメージに関係している。"))
						message(_("短剣や片手剣など、攻撃回数が多い武器は\n安定したダメージを与えられる分\n一撃あたりの破壊力は今ひとつだ。"))
						message(_("逆に両手剣や槍などの武器は、重さのために攻撃回数が少なく\nダメージが安定しない代わりに、一撃あたりの破壊力に優れる。\n\n装甲の厚い相手には、こちらの方が有効打になりうるな。"))
						message(_("基本的にはこの二つ、武器威力と攻撃回数を参考にして選べばいいだろう。\n\nああ、あとはどれだけその武器に熟練しているかも重要だ。\n使い慣れた武器ほど、$c[em]攻撃が命中しやすくなる$cからな。"))
					when :special_weapon
						message(_("武器にはさまざまな種類のものがあるが\nその中でも弓と杖は少し特殊だ。"))
						message(_("弓は両手武器で、後列から攻撃できるというメリットがあるが\n一発ごとに$c[em]手持ちの矢を使わなくてはならない。$c\nもちろん矢が無くなれば攻撃できないから、補充は常に切らすなよ。"))
						message(_("杖は片手用の武器だが、叩くためのものではない。\n術の発動を助けるためのものだ。\n\n優秀な杖を持てば、術の威力はより高まるだろう。"))
					when :armor
						message(_("鎧・外套は、どちらも体を守るための防具だ。\n１人がひとつだけ装備できる。"))
						message(_("基本的には、どの防具もダメージを軽減するためのものだ。\n外套の場合は、回避の助けにもなる。"))
						message(_("重いものを装備できるなら「防護力」の高い鎧を\nそうでなければ、「回避補正」が大きい外套を身につけるのが良いだろう。\n\nもちろん、敵の種類やパーティーの構成次第だがな。"))
					when :shield
						message(_("盾は戦士に限らず、前衛に立つ者すべてにとって重要な防具だ。\n敵から受けるダメージを大きく減少させてくれる。"))
						message(_("小型盾・大型盾の二種類があって\n大きな盾ほど防御に成功する確率が高い。\nできれば大型のほうが良いな。"))
						message(_("ただし、盾で攻撃を防げるのは、ふつう$c[em]1ラウンドあたり1回だけ$cだ。\n\nつまり、多くの敵から集中攻撃を受ければ\nとても盾では防ぎきれないということになる。\n敵の数が多いときには注意しろ。"))
						message(_("また、そもそも盾を使えない場合もある。\nたとえば両手を使ったラウンドには、盾を構えられないし\n呪文を唱えているとき、眠りや痺れなどで動けないときも同じだ。\n\n死にたくないなら、迂闊に隙を見せないようにすることだな。"))
					when :damage_type
						message(_("攻撃にはそれぞれ、何らかの属性があって\n相手によっては$c[em]一部の属性の攻撃が効きにくい。$c\n\nたとえば、スライムなどの軟体生物には\n打撃攻撃（棍棒や素手による攻撃）がほとんど効かない。"))
						message(_("もし攻撃してみて、命中したはずなのに手応えがないと感じられたら\n違った攻撃を試してみることだな。\n\n前述のスライムなら、剣や斧などを使えばいい。"))
						message(_("また、これは敵からの攻撃を防ぐときも同じだ。\n適切な防具やアクセサリーを身につけていれば\n強力な攻撃も、ある程度まで無力化することができるだろう。"))
					when :block
						message(_("ブロックとは、仲間を庇うように前に立ち\n敵の攻撃を一身に集めることだ。\n仲間が危機に瀕しているときに役に立つだろう。"))
						message(_("とはいえ、パーティー全員に及ぶような\n広範囲の攻撃はとても防ぎきれない。\n防げるのは、あくまで一人を対象とする攻撃だけだ。"))
						message(_("また、自分の身を守るわけではないから\n打たれ弱い者がブロックを試みるのは危険だ。\n可能な限り、重装備の戦士に任せるのがいい。\n\nとはいえ、状況によってはそうも言ってられんだろうがな。"))
					when :death
						message(_("ダメージを受けてHPが0以下になると、回復するまで武器を振るえなくなり\nさらに傷の度合いによっては死んでしまう。\n死んだ仲間は、もちろん何もできなくなる。"))
						message(_("死んだ仲間を復活させてほしい時？\n「魔道士のあなぐら」に依頼するしかない。ただし高くつくぞ。"))
						message(_("その上、確実に復活できるとは限らん。\n復活が失敗して、$c[em]霊魂$cになってしまうことがある。\n\n霊魂からでも復活はできるが……\n大金が必要になるうえに、妙な副作用もあるらしい。"))
						#message(_("仲間の死はできる限り避けるべきだ。\n危ないと思ったらすぐに逃げろ。\nそうしないと、貴重な仲間を失ってしまうかもしれん。"))
					end
				end
				
			when :explorer
				message(_("よく来たね。まずはあたしに酒を一杯奢ってもらおうか。\nそうすればあんたたちに、探索のイロハを教えてやるよ。\n\n何が聞きたいんだい？"))
				items = []
				items << SelectItem.new(:enemy, s_("Advice|敵との遭遇"))
				items << SelectItem.new(:escape, s_("Advice|逃走"))
				items << SelectItem.new(:treasure, s_("Advice|宝箱と罠"))
				items << SelectItem.new(:treasure_pattern, s_("Advice|宝物の傾向"))
				items << SelectItem.new(:cancel, s_("Advice|話を聞くのを止める"))
				self.talk(items) do |id|
					case id
					when :enemy
						#message(_("迷宮内で一番恐ろしいのは、言うまでもなく敵と出くわすことだ。\n遭うのは獣やら爬虫類やらがほとんどだけど\n場所によっては野盗や精霊、幽霊なんかもウロチョロしてる。"))
						message(_("一口に敵と遭遇するといっても、二つのパターンがある。\n\nまず一つは、通路や部屋を歩いている最中に\n徘徊している奴らとばったり遭遇すること。\nもう一つは部屋に居座ってる奴らと遭遇することだ。"))
						message(_("この二つで厄介なのは、部屋に居る奴らのほうだね。\n戦って撃退しない限り、その部屋を通してくれないし\n数もたいてい徘徊してる奴らより多い。"))
						message(_("でもその分、そいつらの隠した宝箱が手に入ることがあるのは魅力的だよ。\n通路を歩いてる奴らは宝箱を持ってないからね。"))
						message(_("敵と遭いたくないならどうするかって？\n徘徊してる敵は、道具屋で売ってるお香を焚けば近づいてこないよ。\n\n部屋の敵は……まぁ、回り道するぐらいしかないね。\n扉の前で聞き耳立てれば、たぶん敵の有無ぐらいは分かるだろ。"))
					when :escape
						message(_("「勝てそうにない」と思ったなら、さっさと逃げちまいな。\n長生きしたいのなら、逃げ足が速いに越したことはないよ。"))
						message(_("ただし、逃げるのならできるだけ早いうちの方がいい。\n戦いが長引くと乱戦になってきて、どんどん逃げにくくなるからね。"))
					when :treasure
						message(_("部屋に居る敵を倒したとき、あるいは迷宮探索の途中で\n宝箱を見つけることがある。"))
						message(_("ただし、間違ってもすぐに開けようとはしないこと！\n宝箱にはたいてい罠が仕掛けてあるからね。\n敵に勝って罠に殺される、なんてのはありふれた話だよ。"))
						message(_("最初に「調べる」コマンドで罠の種類を判別する。\nそのあと、その罠をひとつずつ解除する。\n\nまずはこの作業を忘れずにね。"))
						if (explorer = GS.party.members.find{|x| x.kind_of?(Explorer)}) then
							message(_("幸い、あんたらのパーティーには探検家がいるようだから\n%{explorer}にでも罠を解除してもらえばいいだろうね。").evaluate(:explorer => explorer.name))
							message(_("ただし、油断してはいけないよ。\nいくら探検家でも、難度の高い罠なら判別・解除に失敗することもある。"))
							message(_("罠外しの技術は、実際に罠を触ることで上達していくから\nまずは簡単な罠を狙うと安全だよ。\n石つぶてとか、ニードルとかね。"))
							message(_("逆に爆弾やテレポーターなんかはヤバい。\n慣れないうちは手を出さないほうがいいだろう。"))
						else
							message(_("おや？　あんたらのパーティーには探検家がいないのかい？\n\n探検家以外が宝箱を開けようとするのは、あまりオススメしないよ。\n罠の判別をミスって死ぬことがあるからね。"))
							message(_("それでも開けたいのなら、せめて体力のあるヤツが開けな。\nもちろん爆弾に当たれば無事じゃ済まないだろうがね。"))
						end
					when :treasure_pattern
						message(_("ある程度、探索を続けていけばわかると思うけど……\n$c[em]宝箱の中身には傾向がある。$c"))
						message(_("どういうことかっていうとね……\nある部屋には武器の入った宝箱ばかりが出る。\n別のある部屋では、装飾品の入った宝箱ばかりが見つかる。\n\nこんな風に、場所によって出てくる宝物に違いがあるんだよ。"))
						message(_("だから、たとえば強い武器が欲しいときには\n武器の出やすい部屋を見つけて、そこを狙うのがいい。\nそうすれば、お目当てのモノも早く見つかるだろうさ。"))
					end
				end
			when :magician
				message(_("……呪文について、何か聞きたいことでも？"))
				items = []
				items << SelectItem.new(:learn_spell, s_("Advice|呪文の習得"))
				items << SelectItem.new(:mp, s_("Advice|魔力(MP)の消耗と回復"))
				items << SelectItem.new(:better_spell, s_("Advice|どの呪文を習得すれば良いか？"))
				items << SelectItem.new(:get_new_spell, s_("Advice|新しい呪文書の発見"))
				items << SelectItem.new(:get_new_trick, s_("Advice|新しい術の習得"))
				items << SelectItem.new(:cancel, s_("Advice|話を聞くのを止める"))
				self.talk(items) do |id|
					case id
					when :learn_spell
						message(_("……「魔道士のあなぐら」に行くといい。\n術師か学者がいれば、そこで習得できる。費用はかからん。"))
						message(_("一度に習得できる呪文の数には限りがあるが\nレベルが上がれば、多くの呪文を記憶できるようになるだろう……。"))
					when :mp
						message(_("……術を使うと、身体に蓄えた魔力(MP)を消耗する。\n強力な術ほど、多くの魔力を消費してしまう。"))
						message(_("失った魔力を回復するには普通、十分な休息が必要だ。\n宿屋で一週間ほど眠れば、元通りに回復しているだろう……。"))
					when :better_spell
						message(_("……一概には言えんが\nよく分からないうちは「回復」「幻視」を覚えておけばいい。\n\nとくに幻視の基本術「サイトビジョン」は\n現在地とフロアの構造を把握できる、きわめて有用な術だ。"))
					when :get_new_spell
						message(_("……ときどき宝箱から、$c[em]呪文書$cが見つかることがある。\n\nもし見つけたら、大事に持って帰ることだ。\n新しい呪文を扱えるようになる……。"))
					when :get_new_trick
						message(_("……戦って経験を積むといい。\nレベルが上がれば新しい術を習得できる。"))
						message(_("ただし、その時に覚えている呪文だけだ。\n火炎の呪文だけしか習得していないなら\n火炎の術しか習得できん……。"))
					end
				end
			when :cancel
				on_cancel
			end
			
			SELECT_WINDOW.warp
		end
		
		
		def talk(items)
			id = nil
			loop do
				id = Game.select(items){|window|
					window.make_surface(300, 8)
					window.display_max = 8
					window.update
					window.centering
					window.set(id) if id
					window.regulate_display
				}
				if id == :cancel then
					break
				else
					yield(id)
				end
			end
		end
		
		def on_cancel
			Phase.change(BarMenuPhase.new)
			SELECT_WINDOW.set(:expert_talk).warp
		end
	end
	
	class BarMemberJoinPhase < Phase
		include BackablePhase
	
		def on_enter(from)
			super
			@member_window = OtherMemberWindow.new
			$windows = [PARTY_WINDOW, @member_window]
			@member_window.make_surface(8)
			@member_window.update(GS.bar_member_ids.map{|x| GS.members[x]})
			@member_window.reset_index.warp
			

		end
		
		def on_leave(to)
			@member_window = nil
		end
		
		def on_select(id)
			return unless id
			selected = @member_window.members[id]
			member_id = GS.members.index(selected)
			if GS.party.join_member(member_id) then

				GS.bar_member_ids.delete(member_id)
				Game.save(FQ_SMALL_CHANGE, "#{selected.name}がパーティーに加入")
				@member_window.update(GS.bar_member_ids.map{|x| GS.members[x]}).regulate_index
				full_check

				PARTY_WINDOW.update
			end
		end
		
		def full_check
			if GS.party.full? then
				@member_window.select_items.each{|x| x.disable}
				@member_window.update_surface
			end
			
		end
		
		def on_cancel
			super
			Game.save(FQ_CHANGE, "パーティー変更完了")
			SELECT_WINDOW.set(:join).warp
		end
		
	end
	

	
	class HermitageMenuPhase < Phase
		def on_enter(from)
			$windows = [PARTY_WINDOW, CAPTION_WINDOW, WARNING_WINDOW, DESCRIPTION_WINDOW, SELECT_WINDOW]
			select_items = SELECT_WINDOW.select_items.clear
			select_items << SelectItem.new(:spell_learning, _("呪文の習得(S)"), SDL::Key::S)
			select_items.last.description = _('術師・学者に新たな呪文を習得させる')
			select_items.last.disable(_("呪文を扱えるキャラクターがいません")) unless GS.party.members.find{|x| x.spell_caster?}
			select_items << SelectItem.new(:revive, _("蘇生を依頼する(R)"), SDL::Key::R)
			select_items.last.description = _('死亡したキャラクターを蘇生してもらう。依頼には金が必要')
			select_items.last.disable(_("パーティー全員が生きています")) if GS.party.dead_members.empty?
			select_items << SelectItem.new(:revive_result, _("蘇生の結果を聞く"))
			select_items.last.description = _('蘇生儀式の結果を教えてもらう')

			if GS.revived_member_ids.empty? and GS.reviving_member_ids.empty? then
				select_items.last.disable(_("儀式の終わったキャラクターがいません")) 
			end
			
			select_items.each{|x| x.disable} if GS.party.members.empty?
			
			select_items << SelectItem.new(:cancel, _("戻る"))
			select_items.last.description = _('街に戻る')

			
			CAPTION_WINDOW.make_surface(200, 1).update(_("魔道師のあなぐら")).set_position(:center, 80)
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size).dock_beside(CAPTION_WINDOW, :bottom)
			SELECT_WINDOW.reset_index.warp
			WARNING_WINDOW.reset(_("儀式の終わったキャラクターがいません")).dock_beside(SELECT_WINDOW, :bottom)
			on_change
		end
		
		def on_select(id)
			case id
			when :spell_learning
				PARTY_WINDOW.update_items
				PARTY_WINDOW.select_items.each do |item|
					member = GS.party.members[item.id]
					
					unless member.spell_caster? then
						item.disable
					end
				end

				index = Game.member_select(_("だれが？"))
				if index then
					$member_index = index
					Phase.change(SpellSetupPhase.new)
				else
					SELECT_WINDOW.warp
				end
			when :revive
				Phase.change(ReviveTargetSelectPhase.new)
			
			when :revive_result
				if GS.revived_member_ids.empty? then
					Phase.change(ReviveResultPhase.new)
				else
					if Game.ask(_("儀式は終わった\n結果を聞く準備はできているか？")) then
						Phase.change(ReviveResultPhase.new)
					end
				end
			when :cancel
				self.on_cancel
			end
			
		end
		
		def on_cancel
			Phase.change(TownMenuPhase.new)
			SELECT_WINDOW.set(:hermitage).warp
		end
	end
	
	class SpellSetupPhase < StatusSpellSelectPhase
		def on_enter(from)
			super
		end
		
		def hide_unusable_trick?
			false
		end


		def update_spell_window
			columns = @spell_window.columns.clear
			columns << ColumnItem.new(s_("ColumnCaption|NAME"), [], 120, AL_LEFT, 8)
			columns << ColumnItem.new(s_("ColumnCaption|MP"), [], 50, AL_RIGHT, 8)
			columns << ColumnItem.new(s_("ColumnCaption|MASTERY"), [], 70, AL_RIGHT)
			@spell_window.select_items.clear
			member = Game.current_member
			if member.spell_caster? then
				DB.spells.each do |spell|
					if spell.default? or spell.id.in?(GS.got_spell_ids) then
						symbol = (member.spells.include?(spell.id) ? _("L ") : "  ")
						@spell_window.select_items << SelectItem.new(spell.id, symbol + spell.name)
						if not member.spells.include?(spell.id) and member.spells.size >= member.spell_max then
							@spell_window.select_items.last.disable
						end
						columns[1].captions << sprintf("%2d", member.mp_max[spell.id])
						columns[2].captions << sprintf("%d%%", member.get_spell_mastery(spell.id))
					end
				end
			end
			@spell_window.update.regulate_index
		end

		def on_select(id)
			member = Game.current_member
			unless trick_selecting? then
				items = []
				if member.spells.include?(id) then
					items << SelectItem.new(:set, _('習得解除'))
				else
					items << SelectItem.new(:set, _('習得'))
					
					# MEMO: 選択肢をdisableするので、この処理は不要
					#if not member.spells.include?(id) and member.spells.size >= member.spell_max then
					#	items.last.disable('これ以上呪文を習得できない')
					#end
				end
				
				items << SelectItem.new(:trick_check, _('使える術の確認'))
				
				re = Game.select(items){|win|
					#win.dock_beside(@spell_window, :right, 2)
					win.top = @spell_window.top + @spell_window.line_top(@spell_window.index - @spell_window.display_top + 1) + 8
					win.left = @spell_window.left + 16
				}
				case re
				when :set
					SE.equip
					if Game.current_member.spells.include?(id) then
						Game.current_member.spells.delete(id)
					else
						Game.current_member.spells << id
					end
					Game.current_member.spells.compact!
					Game.save(FQ_SMALL_CHANGE, '呪文習得')
					update_sequence
					update_spell_window
					@spell_window.warp
				when :trick_check
					super
				when :cancel
					@spell_window.warp
				end
			end
		end
		
		def on_cancel_from_spell
			Phase.change(HermitageMenuPhase.new)
			SELECT_WINDOW.reset_index.warp
			Game.save(FQ_CHANGE, "呪文習得完了")
		end
	end

	class ReviveTargetSelectPhase < Phase
		include BackablePhase
		def initialize(default_member_id = nil)
			@default_member_id = default_member_id
		end
		
		def on_enter(from)
			super
			
			@member_window = SelectableWindow.new
			@member_window.make_surface(240, 8)
			@member_window.display_max = 8

			@caption_window = TextWindow.new
			@caption_window.text = _('誰を蘇生させる？')
			@caption_window.align = AL_CENTER
			@caption_window.make_surface(@member_window.width, 1).update
			
			@member_window.centering
			@caption_window.centering_on_window(@member_window)
			Window.centering_y([@caption_window, @member_window])
			WARNING_WINDOW.dock_beside(@member_window, :bottom)
			
			update_sequence
			if @default_member_id then
				@member_window.set(@default_member_id).warp
			end
			
			$windows = [WARNING_WINDOW, PARTY_WINDOW, @caption_window, @member_window]
			WARNING_WINDOW.reset(_("金が足りない"))
			
			@member_window.on_change
		end
		
		def update_sequence
			@dead_member_ids = (GS.party.member_ids + GS.bar_member_ids).find_all{|x| GS.members[x].dead?}
			#columns = [ColumnItem.new('FEE', @dead_members.map{|x| x.revive_cost.to_s}, 40, AL_RIGHT)]
			selects = []
			@dead_member_ids.each do |id|
				member = GS.members[id]
				if member.soul? then
					selects << SelectItem.new(id, member.name, nil, '??')
				else
					selects << SelectItem.new(id, member.name, nil, member.revive_cost.to_s)
					if GS.party.gold < member.revive_cost then
						selects.last.disable(_('金が足りない'))
					end
				end
			end
			@member_window.update(selects)
			@member_window.reset_index.warp
			on_change
		end
		
		def on_change
			super
			
			item = @member_window.current_item
			if item and item.enabled? and not GS.members[item.id].soul? then
				fees = GS.party.allocate_fees(GS.members[item.id].revive_cost)
				captions = fees.map{|x| (x >= 1 ? "-#{x}" : '')}
			else
				captions = []
			end
			
			PARTY_WINDOW.update([ColumnItem.new(s_("ColumnCaption|FEE"), captions, 50, AL_RIGHT, 10)])
		end
		
		def on_leave(to)
			@member_window = nil
			PARTY_WINDOW.update([])
		end
		
		def on_select(id)
			return unless id
			member = GS.members[id]
			
			if member.soul? then
				Phase.change(SoulRevivePhase.new(id))
			else
				if Game.ask(_("%{dead}の蘇生には金貨%{fee}枚が必要になるが\nよろしいか？").evaluate(:fee => member.revive_cost, :dead => member.name)) then
					SE.coin
					GS.party.lose_gold(member.revive_cost)
					
					Game.revive_start(id, 1)
					update_sequence
					Game.save(FQ_BIG_CHANGE, "#{member.name}の蘇生を依頼")
					PARTY_WINDOW.update
					message(_("%{member}の蘇生、確かに承った\nあとは儀式の成功を祈りたまえ\n\n一週間後にまたここへ来るがよい").evaluate(:member => member.name))
				end
			end
		end
		
		def on_cancel
			#super
			Phase.change(HermitageMenuPhase.new)
			
			SELECT_WINDOW.set(:revive).warp
		end
		
	end
	
	class ReviveResultPhase < Phase
		include BackablePhase
	
		def on_enter(from)
			super
			
			@member_window = SelectableWindow.new
			@member_window.make_surface(240, 8)
			@member_window.display_max = 8

			@caption_window = TextWindow.new
			@caption_window.text = _('蘇生の結果')
			@caption_window.align = AL_CENTER
			@caption_window.make_surface(@member_window.width, 1).update
			
			
			@member_window.centering
			@caption_window.centering_on_window(@member_window)
			Window.centering_y([@caption_window, @member_window])


			selects = []
			while (id = GS.revived_member_ids.shift) do
				member = GS.members[id]
				member.recover_hp(999)
				GS.bar_member_ids << id
				if member.soul? then
					selects << SelectItem.new(id, member.name, nil, '$[BadColor]' + _("失敗"))
				else
					selects << SelectItem.new(id, member.name, nil, '$[GoodColor]' + _("成功"))
				end
			end
			
			GS.reviving_member_ids.each do |id|
				member = GS.members[id]
				selects << SelectItem.new(nil, member.name, nil, _("あと%{rest}週").evaluate(:rest => member.remaining_week_before_revived))
				selects.last.disable
			end
			
			Game.save(FQ_CHANGE, "蘇生結果を聞いた")
			
			@member_window.update(selects).reset_index.warp
			
			$windows = [PARTY_WINDOW, @caption_window, @member_window]

		end
		
		def on_leave(to)
			@member_window = nil
		end
		
		def on_cancel
			super
			
			SELECT_WINDOW.set(:revive_result).warp
		end
		
	end


	class SoulRevivePhase < Phase
		include BackablePhase
		
		def initialize(member_id, default_inherit = false)
			@member_id = member_id
			@default_inherit = default_inherit
		end
	
		def on_enter(from)
			super
			member = GS.members[@member_id]
			
			BGM.fade_out
			
			
			
			
			@caption_window = TextWindow.new
			@caption_window.text = _("%{member}の蘇生方法を選択してください").evaluate(:member => member.name)
			@caption_window.set_good_width.make_surface.update

			@main_window = SelectableWindow.new
			items = @main_window.select_items.clear
			items << SelectItem.new(:regenerate, _("身体を再構成する"), nil, member.regenerate_cost.to_s)
			if member.life_end? then
				items.last.disable(_("老衰で身体を失った"))
			elsif GS.party.gold < member.regenerate_cost then
				items.last.disable(_("金が足りない"))
			end
			items << SelectItem.new(:inherit, _("魂を継承する"), nil, member.inherit_cost.to_s)
			if GS.party.gold < member.inherit_cost then
				items.last.disable(_("金が足りない"))
			end
			items << SelectItem.new(:cancel, _("キャンセル"))
			@main_window.make_surface(@caption_window.width, 3).update
			@main_window.silent = true
			
			@guide_window = TextWindow.new
			@guide_window.has_frame = false
			@guide_window.make_surface(SCREEN_WIDTH, 5)
			@guide_window.align = AL_CENTER
			
			
			@main_window.centering
			@caption_window.centering
			@guide_window.centering
			Window.centering_y([@caption_window, @main_window, @guide_window], :on_screen => true, :margin => 16)
			@main_window.reset_index
			if @default_inherit then
				@main_window.index = 1
			end
			@main_window.warp
			
			$windows = [@caption_window, @guide_window, WARNING_WINDOW, @main_window]

			WARNING_WINDOW.reset(240)
			WARNING_WINDOW.dock_beside(@main_window, :bottom_right)
			
			
			on_change
			
			return

		end
		
		def on_change
			super
			
			captions = []
			
			case @main_window.current_id
			when :regenerate
				@guide_window.text = _(
%Q[元の身体を再生させる(金貨%{fee}枚が必要)
儀式の副作用として、最大ＨＰが増加するが
代わりに経験値が減少し、寿命が縮まる
また、再生を繰り返すと蘇生の失敗率が高くなっていく
儀式が終わるまでに３週間が必要]
).evaluate(:fee => GS.members[@member_id].regenerate_cost)
				

			when :inherit
				@guide_window.text = _(
%Q[新しい冒険者を作成し、その冒険者に記憶を引き継ぐ
レベルは１になり、能力値も初期値に戻るが
レベルアップ時に、ＨＰの最大値の伸びが大きくなる
「所持品」「習得した術」「装備・術の熟練度」は引き継がれる]
).evaluate(:fee => GS.members[@member_id].inherit_cost)
			when :cancel
				@guide_window.text = ''
			end
			@guide_window.update

		end
		
		def on_select(id)
			super
			
			case id
			when :regenerate
				member = GS.members[@member_id]
				GS.party.lose_gold(member.regenerate_cost)
				Game.revive_start(@member_id, 3)
				SE.coin
				Game.message(_("%{member}の蘇生、確かに承った\n\n三週間後にまたここへ来るがよい").evaluate(:member => member.name))
				BGM.play(:Town)
				PARTY_WINDOW.update
				Phase.change(HermitageMenuPhase.new)
				SELECT_WINDOW.set(:revive).warp
			when :inherit
				SE.select
				Phase.change(CharacterNameInputPhase.new(@member_id))
			when :cancel
				on_cancel
			end

		end
		
		def on_cancel
			SE.cancel
			Phase.change(ReviveTargetSelectPhase.new(@member_id))
			BGM.play(:Town)

		end
		

		
	end



	class ShopMenuPhase < Phase

		def on_enter(from)
			super
			$windows = [PARTY_WINDOW, CAPTION_WINDOW, DESCRIPTION_WINDOW, SELECT_WINDOW]
			DESCRIPTION_WINDOW.set_position(8, 8)
			select_items = SELECT_WINDOW.select_items.clear
			select_items << SelectItem.new(:goods, _("雑貨屋(G)"), SDL::Key::G)
			select_items.last.description = _('消耗品を購入する')
			select_items << SelectItem.new(:weapon, _("武器屋(W)"), SDL::Key::W)
			select_items.last.description = _('武器を購入する')
			select_items << SelectItem.new(:armor, _("防具屋(A)"), SDL::Key::A)
			select_items.last.description = _('鎧・盾などを購入する')
			select_items << SelectItem.new(:accessory, _("服飾店(C)"), SDL::Key::C)
			select_items.last.description = _('外套・装飾品などを購入する')
			select_items << SelectItem.new(:identification, _("識別を依頼する(I)"), SDL::Key::I)
			select_items.last.description = _('？のついた未識別アイテムを識別してもらう')
			select_items << SelectItem.new(:sell, _("持ち物を売る(S)"), SDL::Key::S)
			select_items.last.description = _('持っているアイテムを売る。売ったものは店頭に並び、買い戻しが可能')
			select_items << SelectItem.new(:customize, _("武器・防具を改造する"))
			select_items.last.description = _('武器・鎧・盾を改造し、性能を変化させる')
			

			if Game.debug_mode? then
				select_items << SelectItem.new(:bank, "＊銀行")
			end

			select_items << SelectItem.new(:debug, "＊デバッグ用の品揃え", SDL::Key::F) if Game.debug_mode?
			select_items << SelectItem.new(:cancel, _("戻る"))
			select_items.last.description = _('街に戻る')
			
			CAPTION_WINDOW.make_surface(240, 1).update(_("商店街")).set_position(:center, nil)
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size)
			Window.centering_y([CAPTION_WINDOW, SELECT_WINDOW])
			SELECT_WINDOW.dock_beside(CAPTION_WINDOW, :bottom).warp
			
			on_change
		end
		
		def on_select(id)
			super
			
			case id
			when :cancel
				self.on_cancel
				return
			when :customize
				Phase.change(ItemCustomizePhase.new)
			when :bank
				items = []
				items << SelectItem.new(:deposit, 'お金を預ける')
				items << SelectItem.new(:withdraw, 'お金を引き出す')
				items << SelectItem.new(:cancel, 'キャンセル')
				
				re = Game.select(items)
				$deposit ||= 0
				case re
				when :deposit
					max = (GS.party.gold / 100).to_i * 100
					msg = "何枚の金貨を預けますか？(100枚単位)\n  現在の預金額: %{deposit}" % {:deposit => $deposit}
					mount = Game.number_input(msg, 0, 0..max, :step => 100, :caption_line => 2, :silent => true) || 0
					if mount >= 1 then
						SE.coin
						GS.party.lose_gold(mount)
						$deposit += mount
					else
						SE.cancel
					end
				when :withdraw
					msg = "何枚の金貨を預けますか？(100枚単位)\n  現在の預金額: %{deposit}" % {:deposit => $deposit}
					mount = Game.number_input(msg, 0, 0..$deposit, :step => 100, :caption_line => 2, :silent => true) || 0
					if mount >= 1 then
						SE.coin
						GS.party.members.first.get_gold(mount)
						$deposit -= mount
					else
						SE.cancel
					end
				end
				PARTY_WINDOW.update
				
			when :sell
				Phase.change(ShopSellPhase.new)
			when :identification
				Phase.change(IdentificationPhase.new)
			when :goods, :weapon, :armor, :accessory, :find, :debug
				case id
				when :weapon
				product_type = PD_WEAPON
				when :armor
					product_type = PD_ARMOR
				when :accessory
					product_type = PD_ACCESSORY
				when :goods
					product_type = PD_GOODS
				when :find
					product_type = PD_FIND
				when :debug
					product_type = PD_DEBUG
				end
				index = Game.member_select("だれが？")
				if index then
					$member_index = index
					Phase.change(ShopBuyPhase.new(product_type))
				else
					SELECT_WINDOW.show.warp
				end

			end
		end
		
		def on_cancel
			
			Phase.change(TownMenuPhase.new)
			SELECT_WINDOW.set(:shop).warp
			$phase.on_change

		end
		
	end




	class ShopBuyPhase < BuyPhase
		def initialize(product_type)
			@product_type = product_type
		end
		
		def update_list
			@product_data.clear
		
			# デフォルト商品
			COMMON_LINEUP[@product_type].each do |symbol|
				product = ITEM_SAMPLES[symbol]
			
				@product_data << [product, nil]
			end
			
			# 特殊アイテム
			if @product_type == PD_GOODS and GS.rule.use_visionary_paper? then
				@product_data << [Item.new('VisionaryPaper'), nil]
			end
			
			# 在庫限り商品
			lineup_data = GS.shop_stocks.to_a.sort!{|a, b| ITEM_SAMPLES[a[0]].price <=> ITEM_SAMPLES[b[0]].price}
			lineup_data.each do |symbol, stock|
				product = ITEM_SAMPLES[symbol]
				next unless product.product_type == @product_type
				next if COMMON_LINEUP[@product_type].include?(symbol)
				
				@product_data << [product, stock]
			end


		
			@list_window.update(@product_data)
			
			if @list_window.select_items.empty? then
				SEAL_WINDOW.centering_on_window(@list_window).show
				DESCRIPTION_WINDOW.update('')
			else
				SEAL_WINDOW.hide
			end

		end
	
		
		def buy_sequence
			product = @list_window.current_product
			Game.reporter.on_shop_buy(product)
			if GS.shop_stocks[product.data_id] then
				GS.shop_stocks[product.data_id] -= 1 
				GS.shop_stocks.delete(product.data_id) if GS.shop_stocks[product.data_id] == 0
			end

		end
	
		def on_cancel
			Phase.change(ShopMenuPhase.new)
			case @product_type
			when PD_WEAPON
				id = :weapon
			when PD_ARMOR
				id = :armor
			when PD_ACCESSORY
				id = :accessory
			when PD_GOODS
				id = :goods
			when PD_FIND
				id = :find
			when PD_DEBUG
				id = :debug
			end
			SELECT_WINDOW.set(id).warp
			$phase.on_change
		end

	end
	












	
	class ShopSellPhase < ShopItemSelectPhase
		def get_main_window
			ItemSellWindow.new.make_surface
		end
		
		def on_select(id)
			item = Game.current_member.items[id]
			if Game.ask(_("%{name}を金貨%{price}枚で引き取ってもらいますか？").evaluate(:name => item.name, :price => item.sell_price), :silent => true) then
				SE.coin
				Game.current_member.lose_item(id)
				Game.current_member.get_gold(item.sell_price)
				GS.player_profiles[PPT::GotGoldFromSelling] += item.sell_price
				Game.increment_player_record(PRT::GotGold, PPT::GotGoldFromSelling, item.sell_price)

				GS.shop_stocks[item.data_id] ||= 0
				GS.shop_stocks[item.data_id] += 1
				
				Game.reporter.on_shop_sell(item)
				Game.save(FQ_BIG_CHANGE, "#{Game.current_member.name}が#{item.name}を売却")

				PARTY_WINDOW.update
				@item_window.update.regulate_index.warp
				on_change_member
			else
				SE.cancel
			end
		end

		def on_cancel
			Phase.change(ShopMenuPhase.new)
			SELECT_WINDOW.set(:sell).warp
			$phase.on_change
		end
	end
	
	class IdentificationPhase < ShopItemSelectPhase
		def get_main_window
			IdentificationWindow.new.make_surface
		end

		def on_select(id)
			item = Game.current_member.items[id]
			SE.coin
			item.identify
			Game.current_member.lose_gold(IDENTIFICATION_COST)
			
			Game.reporter.on_item_identify(item)
			Game.save(FQ_BIG_CHANGE, "#{item.name}識別委託")

			message(_("これは%{name}のようですね").evaluate(:name => item.name))

			PARTY_WINDOW.update
			@item_window.update.regulate_index.warp
			on_change_member
		end

		def on_cancel
			Phase.change(ShopMenuPhase.new)
			SELECT_WINDOW.set(:identification).warp
			$phase.on_change
		end
	end
	
	class ItemCustomizePhase < Phase
		include MemberChangablePhase
	
		def on_enter(from)
			super
			$member_index = 0
			WARNING_WINDOW.make_surface
			
			DESCRIPTION_WINDOW.set_position(16, 16)
			DESCRIPTION_WINDOW.update('')

			@item_window = CustomizeItemWindow.new.make_surface
			#@item_window.cursor_evermore_visible = true
			@item_window.dock_beside(DESCRIPTION_WINDOW, :bottom)

			@custom_window = SelectableWindow.new
			@custom_window.make_surface(280, 8)
			@custom_window.display_max = 16
			@custom_window.dock_beside(@item_window, :right)
			
			@change_window = DoubleTextWindow.new.make_surface(200, 4)
			@change_window.inline_tag_usable = true
			@change_window.dock_beside(@custom_window, :bottom)
			
			@price_cache = {}
			PARTY_WINDOW.update
			
			$windows = [PARTY_WINDOW, DESCRIPTION_WINDOW, @custom_window, @change_window, @item_window]
			
			on_change_member
		end
		
		def on_change
			super
			@item_window.update(true)
			if @item_window.current_id then
				item = Game.current_member.items[@item_window.current_id]
				
				case Game.current_window
				when @item_window
					DESCRIPTION_WINDOW.update(item.description)
					
					selects = @custom_window.select_items.clear
					@price_cache.clear
					
					if @item_window.current_item.enabled? then
						SEAL_WINDOW.hide
						ItemPrefix::CUSTOMIZABLE.each do |prefix|
							if item.matched_prefix?(prefix) then
								sample = Item.create(item.data_id, prefix)
								price = (sample.price * 0.6).to_i
								@price_cache[prefix] = price
								
								unless item.prefix == sample.prefix then
									selects << SelectItem.new(prefix, "-> #{sample.name}")
									selects.last.right_caption = price.to_s
									
									if Game.current_member.gold < price then
										selects.last.disable(_("お金が足りません"))
									end
								end
							end
						end
					else
						SEAL_WINDOW.update(_("改造不可")).centering_on_window(@custom_window).show
						@item_window.show
					end
					@custom_window.update
					
					
					@change_window.texts = get_change_texts(item)
					@change_window.update
	
				when @custom_window
					if @custom_window.current_id then
						sample = Item.create(item.data_id, @custom_window.current_id)
					
						@change_window.texts = get_change_texts(item, sample)
						@change_window.update
					end
	
				end
			else # アイテムを持っていない場合
			end
		end

		def on_select(id)
			super
			case Game.current_window
			when @item_window
				@custom_window.reset_index.show

			when @custom_window
				new_prefix = @custom_window.current_id
				price = @price_cache[new_prefix]
				msg = _("金貨%{gold}枚で改造を行います。\nよろしいですか？")
				if Game.ask(msg.evaluate(:gold => price), :silent => true) then
					Game.current_member.items[@item_window.current_id].prefix = new_prefix
					Game.current_member.lose_gold(price)
					SE.equip
					PARTY_WINDOW.update
					Game.save(FQ_BIG_CHANGE, "カスタマイズ")
					@item_window.show
				end
			end
			on_change
			
			return

			
			unless selects.empty? then
				re = Game.select(selects)
				
				unless re == :cancel then
					item.prefix = re
					Game.current_member.lose_gold(@price_cache[re])
					SE.coin
					PARTY_WINDOW.update
					@item_window.update
				end
				
				@item_window.warp
			end
		end

		def on_cancel
			case Game.current_window
			when @item_window

				Phase.change(ShopMenuPhase.new)
				SELECT_WINDOW.set(:customize).warp
				$phase.on_change

			when @custom_window
				@item_window.show
				on_change
			end
		end
		

		def on_right_key
			if Game.current_window == @item_window then
				super
			end
		end
		
		def on_left_key
			if Game.current_window == @item_window then
				super
			end
		end

		
		def on_change_member
			#NAME_WINDOW.update(Game.current_member.name)
			
			if Game.current_member.items.empty? then
				SEAL_WINDOW.update(_("何も持っていない")).centering_on_window(@item_window).show
				@change_window.update([])
			else
				SEAL_WINDOW.hide
				@item_window.update
				@item_window.regulate_index
			end
			super
		end
		
		private
		
		def get_change_color(old, new)
			if old < new then
				"$c[good]"
			elsif old > new then
				"$c[bad]"
			else
				"$c"
			end
		end
		
		def get_change_texts(old_item, new_item = nil)
			re = []
			case old_item.data
			when WeaponModel
				if new_item then
					old = (old_item.damage_rate * 10).to_i
					new = (new_item.damage_rate * 10).to_i
					re << [_("武器威力"), sprintf("%3s -> %s%3s$c", old, get_change_color(old, new), new)]
					
					old = old_item.hitting_bonus
					new = new_item.hitting_bonus
					re << [_("命中補正"), sprintf("%3s -> %s%3s$c", Util.bonus_to_s(old), get_change_color(old, new), Util.bonus_to_s(new))]
					
					old = old_item.avoid_bonus
					new = new_item.avoid_bonus
					re << [_("回避補正"), sprintf("%3s -> %s%3s$c", Util.bonus_to_s(old), get_change_color(old, new), Util.bonus_to_s(new))]
				else
					re << [_("武器威力"), sprintf("%3s       ", (old_item.damage_rate * 10).to_i)]
					re << [_("命中補正"), sprintf("%3s       ", Util.bonus_to_s(old_item.hitting_bonus))]
					re << [_("回避補正"), sprintf("%3s       ", Util.bonus_to_s(old_item.avoid_bonus))]
				end
			when ArmorModel
				if new_item then
					old = old_item.defense
					new = new_item.defense
					re << [_("防護力"), sprintf("%3s -> %s%3s$c", old, get_change_color(old, new), new)]
					old = old_item.avoid_bonus
					new = new_item.avoid_bonus
					re << [_("回避補正"), sprintf("%3s -> %s%3s$c", Util.bonus_to_s(old), get_change_color(old, new), Util.bonus_to_s(new))]
				else
					re << [_("防護力"), sprintf("%3s       ", old_item.defense)]
					re << [_("回避補正"), sprintf("%3s       ", Util.bonus_to_s(old_item.avoid_bonus))]
				end
			when ShieldModel
				if new_item then
					old = old_item.extra_defense
					new = new_item.extra_defense
					re << [_("追加防護力"), sprintf("%3s -> %s%3s$c", Util.bonus_to_s(old), get_change_color(old, new), Util.bonus_to_s(new))]
				else
					re << [_("追加防護力"), sprintf("%3s       ", old_item.extra_defense)]
				end

			end
			
			re
		end
	end




	
	class GuildMenuPhase < Phase
		include BackablePhase
	
		def on_enter(from)
			super
			$windows = [PARTY_WINDOW, CAPTION_WINDOW, WARNING_WINDOW, DESCRIPTION_WINDOW, SELECT_WINDOW]
			select_items = SELECT_WINDOW.select_items.clear
			#select_items << SelectItem.new(nil, "冒険の記録を見る(H)", SDL::Key::H)
			select_items << SelectItem.new(:entry, _("新しい冒険者の登録(E)"), SDL::Key::E)
			select_items.last.description = _('新たな冒険者キャラクターを作成する')
			select_items << SelectItem.new(:rename, _("冒険者の名前を変える(R)"), SDL::Key::R)
			select_items.last.description = _('パーティーにいる冒険者の名前を変える')
			select_items.last.disable if GS.party.members.empty?
			select_items << SelectItem.new(:delete, _("冒険者の抹消(D)"), SDL::Key::D)
			select_items.last.description = _('冒険者キャラクターを削除する(復帰不可)')
			select_items.last.disable if GS.bar_member_ids.empty?
			select_items << SelectItem.new(:history, _("冒険者たちの記録を見る(H)"), SDL::Key::H)
			select_items.last.description = _('これまでの戦闘回数など、さまざまな記録を表示する')
			select_items.last.disable if GS.members.empty?
			select_items << SelectItem.new(:book, _("発見したものの記録を見る(B)"), SDL::Key::B)
			select_items.last.description = _('今までに発見したアイテム・術・敵を一覧表示する')
			select_items.last.disable if GS.members.empty?
			
			if Game.debug_mode? or GS.switch['BetaScenarioClear'] then
				select_items << SelectItem.new(:bgm, _("BGM演奏"))
				select_items.last.description = _('BGMを自由に聴くことができる')
			end

			#select_items << SelectItem.new(:config, "#{_('ゲーム設定')}(C)", SDL::Key::C)
			select_items << SelectItem.new(:cancel, _("戻る"))
			select_items.last.description = _('街に戻る')
			
			CAPTION_WINDOW.make_surface(220, 1).update(_("冒険者ギルド")).set_position(:center, 80)
			SELECT_WINDOW.make_surface(CAPTION_WINDOW.width, select_items.size).update
			SELECT_WINDOW.dock_beside(CAPTION_WINDOW, :bottom)
			SELECT_WINDOW.reset_index.warp
			WARNING_WINDOW.reset
			on_change
		end
		
		def on_select(id)
			super
			case id
			when :entry
				Phase.change(CharacterNameInputPhase.new)
			when :rename
				$member_index = Game.member_select(_("だれの？"))
				if $member_index then
					Phase.change(CharacterRenamePhase.new)
				else
					SELECT_WINDOW.show.warp
				end
			when :history
				Phase.change(HistoryPhase.new)
				
			when :config
				Phase.change(TownGameConfigPhase.new)
			when :delete
			
				
				Phase.change(CharacterDeletePhase.new)
			when :book
				Phase.change(BookPhase.new)
			
			when :bgm
				items = []
				%w(Town Camp Dungeon1 Dungeon2 NPC1 NPC2 Battle BossBattle).each do |bgm_str_id|
					#if GS.found_bgm?(bgm_str_id) then
						items << SelectItem.new(bgm_str_id, BGM_TITLES[bgm_str_id.to_sym])
					#else
					#	items << SelectItem.new(nil, '----------------')
					#end
				end
				
				last = nil
				loop do
					re = Game.select(items, :default_id => last, :silent => true)
					case re
					when :cancel
						SE.cancel
						BGM.play(:Town)
						break
					else
						BGM.stop
						sleep(0.1)
						BGM.play(re.to_sym)
						last = re
					end
				end

			when :cancel
				self.on_cancel
			end
		end
		
		def on_cancel
			
			Phase.change(TownMenuPhase.new)
			SELECT_WINDOW.set(:guild).warp
			$phase.on_change
		end
		
		
		
	end
	
	
	class HistoryPhase < Phase
		def on_enter(from)
			super
			SELECT_WINDOW.make_surface(200, 14)
			SELECT_WINDOW.display_max = 14
			items = SELECT_WINDOW.select_items.clear
			
			items << SelectItem.new(:player, _('プレイヤー情報'))
			GS.members.each_index do |id|
				if GS.members[id] then
					items << SelectItem.new(id, GS.members[id].name)
				end
			end
			SELECT_WINDOW.set_position(16, 16)
			
			#@history_window = MultiColumnWindow.new.make_surface(360, 10)
			#columns = @history_window.columns.clear
			#columns << ColumnItem.new('WEEK', %w(1 3 6 9 12 15 15), 40, AL_RIGHT)
			#columns << ColumnItem.new('DESCRIPTION', %w(17歳で冒険者ギルドに登録 はぐれ術師のアイスボルトで死亡 復活する レベルが2に上昇 18歳を迎える インプの攻撃で死亡 身体を失い、大地へと還る), 300, AL_LEFT)
			#@history_window.dock_beside(SELECT_WINDOW, :right).update
			
			@count_window = DoubleTextWindow.new.make_surface(240, 12)
			@count_window.dock_beside(SELECT_WINDOW, :right)
			
			@guide_window = TextWindow.new.make_surface(@count_window.width)
			@guide_window.update(_('決定キーで熟練度の一覧を表示'))
			@guide_window.dock_beside(@count_window, :bottom)
			
			@inheritance_window = TextWindow.new.make_surface(@count_window.width, 5).dock_beside(@guide_window, :bottom)
			@inheritance_window.has_caption = true
			
			
			SELECT_WINDOW.update.reset_index.warp
			$windows = [@count_window, @guide_window, SELECT_WINDOW]
			
			on_change
		end
		
		def on_change
			texts = []
			
			if Game.current_window == SELECT_WINDOW then
				if SELECT_WINDOW.current_id == :player then
					texts = []
					PPT::LIST.each do |key|
						texts << [PPT::CAPTIONS[key], GS.player_profiles[key]]
					end
					
					hour = GS.playing_time / 60 / 60
					min = GS.playing_time / 60 - hour * 60
					if hour >= 1 then
						time = sprintf("%3d時間%02d分", hour, min)
					else
						time = sprintf("%2d分", min)
					end
					texts << [_('プレイ時間'), time]
					@guide_window.hide
					@inheritance_window.hide
					SELECT_WINDOW.show
	
				else
					member = GS.members[SELECT_WINDOW.current_id]
					texts = []
					texts << [_('レベル'),  member.level]
					if member.existing? then
						texts << [_('年齢'), member.age]
					else
						texts << [_('最終年齢'), member.age]
					end
					texts << [_('登録'), _('第%{week}週').evaluate(:week => member.profiles[MPT::CreatedWeek])]
					if member.existing? then
						texts << []
					else
						texts << [_('引退'), _('第%{week}週').evaluate(:week => member.profiles[MPT::LostWeek])]
					end
					
					f = member.profiles[MPT::ForwardRound]
					b = member.profiles[MPT::BackRound]
					total = f + b
					if total >= 1 then
						texts << [_('前列:後列'), "#{f * 100 / total}:#{b * 100 / total}"]
					else
						texts << [_('前列:後列'), "?"]
					end
	
	
					texts << [_('勝利回数'), member.profiles[MPT::Win]]
					texts << [_('逃走回数'), member.profiles[MPT::Escape]]
					texts << [_('殺した敵の数'), member.profiles[MPT::Kill]]
					texts << [_('蘇生回数'), member.profiles[MPT::Revived]]
					texts << ['  ' + _('霊魂からの蘇生'), member.regenerated]
					texts << [_('累積歩数'), member.profiles[MPT::Walk]]
					texts << [_('消費MP累計'), member.profiles[MPT::UsedMP]] if member.spell_caster?
					
					if member.inherited_member_ids.empty? then
						@inheritance_window.hide
					else
						list = [_('魂の継承')] + member.inherited_member_ids.map{|x| GS.members[x].name}
						@inheritance_window.update(list.join("\n"))
						@inheritance_window.show
					end
					
					@guide_window.show 
					SELECT_WINDOW.show
		
	
				end
				@count_window.update(texts)
			end
		end
		
		def on_select(id)
			if id == :player then
				return
			end
			
			last_selected = nil
			loop do
		
				member = GS.members[id]
				items = []
				items << SelectItem.new(:weapon_mastery, _("武器の熟練"))
				items << SelectItem.new(:armor_mastery, _("防具の熟練"))
				items << SelectItem.new(:shield_mastery, _("盾の熟練"))
				items << SelectItem.new(:spell_mastery, _("術の熟練")) if member.spell_caster?
				items << SelectItem.new(:cancel, _('キャンセル'))
				re = Game.select(items, :default_id => last_selected){|win|
					#win.centering_on_screen
					win.dock_beside(SELECT_WINDOW, :right, 2)
					win.top = SELECT_WINDOW.top + SELECT_WINDOW.line_top(SELECT_WINDOW.index - SELECT_WINDOW.display_top)
				}
				last_selected = re
				
				
				items.clear
				if re == :cancel then
					SELECT_WINDOW.warp
					return
				elsif re == :spell_mastery then
					DB.spells.each do |spell|
						mastery = member.get_spell_mastery(spell.id).to_i
						if mastery >= 1 then
							items << SelectItem.new(spell.id, spell.name, nil, "#{mastery}%")
						end
					end
				else
					case re
					when :weapon_mastery
						model_cls = WeaponModel
						symbol = MST::WEAPON
					when :armor_mastery
						model_cls = ArmorModel
						symbol = MST::ARMOR
					when :shield_mastery
						model_cls = ShieldModel
						symbol = MST::SHIELD
					end
					
					DB.items.each do |model|
						if model.kind_of?(model_cls) then
							mastery = member.get_mastery(symbol, model.id).to_i
							if model.usable_by?(member) and mastery >= 1 then
								items << SelectItem.new(model.id, model.name, nil, "#{mastery}%")
							end
						end
					end
				end
	
	
				
				if items then
					if items.empty? then
						items = [SelectItem.new(:cancel, _('熟練しているものがありません'))]
					end
					
					Game.select(items){|win|
							win.make_surface(240, 10)
							win.display_max = 10
							win.centering_on_screen
					}
					
					SELECT_WINDOW.warp
				end
			end
		end
		
		
		def on_cancel
			
			Phase.change(GuildMenuPhase.new)
			SELECT_WINDOW.set(:history).warp
		end
	end


	class BookPhase < Phase
		def on_enter(from)
			super
			
			DESCRIPTION_WINDOW.set_position(16, 16)
			DESCRIPTION_WINDOW.update('')

			@category_window = SelectableWindow.new
			@category_window.cursor_evermore_visible = true
			selects = []
			selects << SelectItem.new('item', _('発見したアイテム'))
			selects.last.disable if GS.found_model_switches['item'].empty?
			selects << SelectItem.new('trick', _('習得した術'))
			selects.last.disable if GS.found_model_switches['trick'].empty?
			selects << SelectItem.new('enemy', _('遭遇した敵'))
			selects.last.disable if GS.found_model_switches['enemy'].empty?
			
			@category_window.select_items = selects
			@category_window.set_good_width.make_surface(nil, selects.size)
			@category_window.dock_beside(DESCRIPTION_WINDOW, :bottom).warp
			
			@list_window = SelectableWindow.new
			@list_window.make_surface(200, 16)
			@list_window.display_max = 16
			@list_window.dock_beside(@category_window, :right)
			
			@item_data_window = ItemDataWindow.new.make_surface.update
			@item_data_window.dock_beside(@list_window, :right)
			
			@trick_data_window = DoubleTextWindow.new
			@trick_data_window.make_surface(200, 2).update
			@trick_data_window.dock_beside(@list_window, :right)
			
			@enemy_graphic_window = Window.new
			@enemy_graphic_window.has_frame = false
			@enemy_graphic_window.make_surface(200, 200).update
			@enemy_graphic_window.dock_beside(@list_window, :right)
			
			@enemy_data_window = DoubleTextWindow.new
			@enemy_data_window.make_surface(100, 2).update
			@enemy_data_window.dock_beside(@enemy_graphic_window, :bottom_center)
			
			$windows = [@list_window, @category_window]
			
			on_change
			
		end
		
		def on_change
			case Game.current_window
			when @category_window
				selects = @list_window.select_items.clear
				
				case @category_window.current_id
				when 'item'
					models = DB.items
				when 'trick'
					models = DB.tricks
				when 'enemy'
					models = DB.enemies
				end
				
				models.each_with_index do |model, i|
					if GS.found_model?(@category_window.current_id, model.id) then
						selects << SelectItem.new(model.id, model.name)
					end
				end
				
				@list_window.reset_index.update
			when @list_window
				case @category_window.current_id
				when 'item'
					model = DB.find_item(@list_window.current_id)
					@item_data_window.update(model)
					DESCRIPTION_WINDOW.update(model.description)
				when 'trick'
					model = DB.find_trick(@list_window.current_id)
					DESCRIPTION_WINDOW.update(model.description)

					texts = @trick_data_window.texts.clear
					texts << [DB.find_spell(model.spell_id).name]
					texts << [_('消費MP'), model.mp_cost]
					@trick_data_window.update
				when 'enemy'
					model = DB.find_enemy(@list_window.current_id)
				
					graphic = ENEMY_GRAPHICS[model.id]
					
					dest = @enemy_graphic_window
					dest.clear_surface
					if graphic.book_surface then
						dest.front_surface.put(graphic.book_surface, 0, 0)
					else
						x = (dest.width - graphic.width) / 2
						y = (dest.height - graphic.height) / 2
						dest.front_surface.put(graphic.surface, x, y)
					end
					
					DESCRIPTION_WINDOW.update(model.description)
					texts = @enemy_data_window.texts.clear
					texts << [_('レベル'), model.level]
					texts << [_('HP'), model.hp_max]
					@enemy_data_window.update
				end
				
				
			end

		end
		
		def on_select(id)
			case Game.current_window
			when @category_window
				case @category_window.current_id
				when 'item'
					@item_data_window.show
				when 'trick'
					@trick_data_window.show
				when 'enemy'
					@enemy_graphic_window.show
					@enemy_data_window.show if Game.debug_mode?
				end
			
				DESCRIPTION_WINDOW.show
				@list_window.show.warp
				on_change
			end
		end
		
		
		
		
		def on_cancel
			case Game.current_window
			when @category_window
				Phase.change(GuildMenuPhase.new)
				SELECT_WINDOW.set(:book).warp
			when @list_window
				@item_data_window.hide
				@trick_data_window.hide
				@enemy_graphic_window.hide
				@enemy_data_window.hide
				@category_window.show.warp
				DESCRIPTION_WINDOW.hide
			end
			
		end
	end








	
	# キャラクター作成フェーズの親となる中小クラス
	class CharacterMakePhase < Phase
		def on_enter(from)
			super
			$windows = [DESCRIPTION_WINDOW, DATA_WINDOW, SELECT_WINDOW]
			SELECT_WINDOW.reset_index
		end
	end
	
	class CharacterNameInputPhase < Phase
		def initialize(inherited_member_id = nil, default = "")
			@inherited_member_id = inherited_member_id
			@default = default
		end
	
		def on_enter(from)
			if Game.full_screen? then
				if Game.ask(_("フルスクリーン表示では文字の入力を行えないため\nウインドウ表示に切り替えます。\n（元に戻したいときには、F1～F4キーを押して\nシステムメニューから「ウインドウ/フルスクリーン切り替え」を選択してください）\n\nよろしいですか？")) then
					Game.full_screen = false
					Game.open_screen(false)
				else
					on_cancel
					return
				end
			end
			temp = GS.game_config.mouse_operation
			GS.game_config.mouse_operation = false
			name = Game.show_name_input_dialog(_("冒険者の名前を入力してください"), @default)
			GS.game_config.mouse_operation = temp

			
			# 名前の表示に必要な長さを調べる
			if name then
				length = 0
				name.each_char.each do |c|
					length += (CHAR_LENGTH_TABLE[c.length])
				end
			end

			if name && GS.members.compact.find{|x| name == x.name} then
				message(_("同じ名前を持つ冒険者が存在します"))
				self.on_cancel
			elsif name && length > 14 then
				message(_("名前が長すぎます\n半角14文字(全角7文字)以内で入力してください"))
				self.on_cancel
			elsif name && (name != '') then
				finish(name)
			else
				self.on_cancel
			end
		end
		
		def finish(name)
			Phase.change(CharacterAgeSelectPhase.new(@inherited_member_id, name))
		end
		
		def on_cancel
			if @inherited_member_id then
				Phase.change(SoulRevivePhase.new(@inherited_member_id, true))
			else
				Phase.change(GuildMenuPhase.new)
				SELECT_WINDOW.set(:entry).warp
			end
		end
	end
	
	class CharacterRenamePhase < CharacterNameInputPhase
		def finish(name)
			
			old_name = Game.current_member.name
			new_name = name
			Game.current_member.name = new_name
			Game.save(FQ_BIG_CHANGE, "名前変更")
			PARTY_WINDOW.update
			message(_("キャラクターの名前を変更しました\n%{old} → %{new}").evaluate(:old => old_name, :new => new_name))
			
			Phase.change(GuildMenuPhase.new)
			SELECT_WINDOW.set(:rename).warp
		end
		
		def on_cancel
			Phase.change(GuildMenuPhase.new)
			SELECT_WINDOW.set(:rename).warp
		end

	end

	

	# キャラクター年齢選択
	class CharacterAgeSelectPhase < CharacterMakePhase
		def initialize(inherited_member_id, name, default = AGE::YOUNG)
			@inherited_member_id = inherited_member_id
			@name = name
			@default = default
		end
	
		def on_enter(from)
			

			super
			DESCRIPTION_WINDOW.set_position(8, 8)
			DESCRIPTION_WINDOW.update(_("初期年齢を選択してください（年齢の違いは寿命にのみ影響します）"))
			DATA_WINDOW.make_surface(200, 3)
			DATA_WINDOW.update([[@name, nil], [_("年齢"), nil], [_("クラス"), nil]])
			DATA_WINDOW.dock_beside(DESCRIPTION_WINDOW, :bottom)
			DATA_WINDOW.right = DESCRIPTION_WINDOW.right

			
			# 選択肢設定
			select_items = SELECT_WINDOW.select_items
			select_items.clear
			select_items << SelectItem.new(AGE::CHILD, AGE_CAPTIONS[AGE::CHILD] + ':' + _('%{min}～%{max}歳').evaluate(:min => 10, :max => 13))
			select_items << SelectItem.new(AGE::YOUNG, AGE_CAPTIONS[AGE::YOUNG] + ':' + _('%{min}～%{max}歳').evaluate(:min => 17, :max => 19))
			select_items << SelectItem.new(AGE::ELDER, AGE_CAPTIONS[AGE::ELDER] + ':' + _('%{min}～%{max}歳').evaluate(:min => 25, :max => 28))
			select_items << SelectItem.new(AGE::OLD, AGE_CAPTIONS[AGE::OLD] + ':' + _('%{min}～%{max}歳').evaluate(:min => 60, :max => 63))
			SELECT_WINDOW.make_surface(150, 4).centering(true)
			SELECT_WINDOW.set(@default).warp


		end

	
		def on_select(id)
			super
			# 履歴表示
			table = AGE_CAPTIONS
			Phase.change(CharacterClassSelectPhase.new(@inherited_member_id, @name, id))
		end
		
		def on_cancel
			Phase.change(CharacterNameInputPhase.new(@inherited_member_id, @name))

		end

	end

	# キャラクタークラス選択
	class CharacterClassSelectPhase < CharacterMakePhase
	
		def initialize(inherited_member_id, name, age)
			@inherited_member_id = inherited_member_id
			@name = name
			@age = age
		end

		def on_enter(from)
			super
			DATA_WINDOW.texts[1][1] = AGE_CAPTIONS[@age]
			DATA_WINDOW.update
			DESCRIPTION_WINDOW.text = _("クラス(職業)を選択してください")
			DESCRIPTION_WINDOW.update
			
			# 選択肢設定
			select_items = SELECT_WINDOW.select_items
			select_items.clear
			
			select_items << SelectItem.new(:Fighter, s_('ClassName|軽戦士'))
			select_items << SelectItem.new(:HeavyFighter, s_('ClassName|重戦士'))
			select_items << SelectItem.new(:Archer, s_('ClassName|弓闘士'))
			select_items << SelectItem.new(:Explorer, s_('ClassName|探検家'))
			select_items << SelectItem.new(:Prayer, s_('ClassName|僧'))
			select_items << SelectItem.new(:Magician, s_('ClassName|術師'))
			select_items << SelectItem.new(:Academian, s_('ClassName|学者'))
			select_items << SelectItem.new(:Grappler, s_('ClassName|格闘家'))
			
			if GS.rule.use_member_classes then
				select_items.delete_if do |item|
					not GS.rule.use_member_classes.include?(item.id)
				end
			end
			#select_items << SelectItem.new(nil, "#{ClassName::Samurai}(6)", SDL::Key::K6)
			#select_items << SelectItem.new(nil, "#{ClassName::Assasin}(7)", SDL::Key::K7)
			#select_items << SelectItem.new(nil, "#{ClassName::Alchemyst}(8)", SDL::Key::K8)
			#select_items << SelectItem.new(nil, "#{ClassName::Wizard}(9)", SDL::Key::K9)
			SELECT_WINDOW.make_surface(120, 8).set_position(20, DATA_WINDOW.bottom + 8)
			SELECT_WINDOW.reset_index.warp
			
			
			# 成長率表示ウインドゥ
			@growth_window = DoubleTextWindow.new.make_surface(120, 6)
			@growth_caption_window = TextWindow.new.make_surface(@growth_window.width, 1)
			@growth_caption_window.align = AL_CENTER
			@growth_caption_window.update(_("能力成長"))

			@growth_caption_window.set_position(SELECT_WINDOW.right + 8, SELECT_WINDOW.top).show
			@growth_window.dock_beside(@growth_caption_window, :under, -1).show
			

			# 解説ウインドゥ
			#@description_window = TextWindow.new.make_surface(450, 4)
			@description_window = TextWindow.new
			@description_window.inline_tag_usable = true
			@description_window.client_width = Game.char_width * 80
			@description_window.make_surface(nil, 6).dock_beside(SELECT_WINDOW, :bottom).show
			@description_window.left = SELECT_WINDOW.left

			

			# 習熟可能ウインドゥ
			@masterable_window = MasterableWindow.new.make_surface
			@masterable_caption_window = TextWindow.new.make_surface(@masterable_window.width, 1)
			@masterable_caption_window.align = AL_CENTER
			@masterable_caption_window.update(_("装備可能"))
			
			@masterable_caption_window.dock_beside(@growth_caption_window, :right).show
			@masterable_window.dock_beside(@masterable_caption_window, :under, -1).show


			SELECT_WINDOW.show
			self.on_change

		end
		
		def on_leave(to)
			unless to.kind_of?(CharacterMakePhase) then
				@growth_window = nil
				@description_window = nil
				@masterable_window = nil
			end
		end
		
		def on_change
			id = SELECT_WINDOW.current_id
			if id then
		
				# 成長値表示
				table = %W(G F E D C B A S SS)
				
				
				model = eval("#{id.to_s}.new")
				#growth.each_pair do |ability_symbol, value|
				#	growth_captions[ability_symbol] = table[value]
				#end
	
				texts = @growth_window.texts.clear
				texts << [_('ＨＰ'), table[model.hp_max_growth]]
				texts << [_('筋力'), table[model.get_ability_growth(STR)]]
				texts << [_('器用さ'), table[model.get_ability_growth(TEC)]]
				texts << [_('素早さ'), table[model.get_ability_growth(AGL)]]
				texts << [_('集中力'), table[model.get_ability_growth(WIL)]]
				texts << [_('霊感'), table[model.get_ability_growth(PSY)]]
				
			else
				@growth_window.texts.each{|x| x[1] = ""}
			end
			@growth_window.update

			# 習熟可表示
			@masterable_window.update(eval(id.to_s)) if id

			# 解説表示
			text = ""
			case id
			when :Fighter
				text << _(
%Q[体力と機動力に優れた、近接戦闘のエキスパート
軽装による防御の薄さを技量でカバーする
しかし一撃の威力が低いため、重装甲の相手は苦手

特技1:猛襲 (攻撃回数増加、ただし盾使用不可)
特技2:フェイント (使用ラウンドのみ相手の回避力を減少)]
				)
			when :HeavyFighter
				text << _(
%Q[重装備で味方の盾となる前衛職
鈍重だが筋力に優れ、ほぼすべての武器・防具を扱える
力任せの一撃による行動妨害が可能

特技:強打 (高威力の一撃＋吹き飛ばし効果。盾使用不可)]
				)
			when :Archer
				text << _(
%Q[弓の扱いに熟達した唯一のクラス
弓矢は強力だが、盾と同時に使えないため防御力に難あり
また一発ごとに矢を消費するため、常にストックが必要

特技:チャージ (１～３ラウンド後に攻撃。命中率と威力にボーナス)]
				)
			when :Magician
				text = _(
%Q[強力な呪文で敵を粉砕し、仲間を守る魔法使い
繰り出す術は強力だが、呪文の習得数が少ないのが難点


特技:ブースト (ＭＰを２倍消費して術の効果上昇)]
				)
			when :Explorer
				text << _(
%Q[遺跡探検・財宝探索に必要なスキルの専門家
戦闘能力は低いが、鍵開け・罠外しにおいて活躍する


特技: 隠れる (攻撃の対象にならない。奇襲で後列から攻撃可)
常動効果:聞き耳が必ず成功する、逃走成功率がアップ]
				)
			when :Prayer
				text = _(
%Q[修行によって魔を打ち払い、死者を鎮める力を身につけた者
その力は、仲間全員に呪文攻撃・呪いに対する守りを与え
霊体タイプの敵を実体化させることができる

特技:祈る (呪文攻撃や呪いを一定確率で無効化)
常動効果:霊体タイプの敵を実体化させる (攻撃の命中率が下がらない)]
				)
			when :Academian
				text = _(
%Q[アイテムや敵に関する知識を備え、呪文も扱う知の探求者
しかし呪文の使用回数は少なく、威力面でも術師に劣る
また筋力・耐久力が低いという欠点もある

常動効果:種類の分からないアイテムを判別できる
         戦闘時に敵のＨＰや、効果の高い/低い攻撃を知ることができる]
				)
			when :Grappler
				text = _(
%Q{$c[warn]* ゲームに慣れたプレイヤー向け *$c
拳や脚で敵を屠る異能の戦士。肉体能力は高いが、武器・防具を装備できない

特技:精密打撃 (敵１体の能力値１つを一時的に減少させる。重複可)
常動効果:素手攻撃の威力・防護力に、レベルに応じたボーナス
         敵１体の武器攻撃をすべて回避すると、カウンター攻撃発動}
				)
			else
				text = ""
			end
			
			@description_window.text = text
			@description_window.update
		end

	
		def on_select(id)
			member_cls = eval(id.to_s)
			member = member_cls.new(1, @age)
			member.name = @name


			
			Phase.change(CharacterBonusPointAllocationPhase.new(@inherited_member_id, member, @age))
		end

		def on_cancel
			Phase.change(CharacterAgeSelectPhase.new(@inherited_member_id, @name, @age))

		end


	end
	
	
	# ボーナスポイント配分
	class CharacterBonusPointAllocationPhase < CharacterMakePhase
		def initialize(inherited_member_id, member, age)
			@inherited_member_id = inherited_member_id
			@member = member
			@age = age
		end

		def on_enter(from)
			super
			DATA_WINDOW.texts[2][1] = @member.class_caption
			DATA_WINDOW.update
			DESCRIPTION_WINDOW.update(_("ボーナスポイントを振り分けてください"))
			
			# 選択肢設定
			@main_window = SelectableWindow.new
			@main_window.select_items.clear

			ABILITY_TYPES.each do |type|
				@main_window.select_items << SelectItem.new(type, ABILITY_CAPTIONS[type])
			end
			
			@main_window.make_surface(200, 5).centering(true)
			@main_window.reset_index.warp

			
			# 残りボーナスの表示ウインドゥ
			@rest_window = DoubleTextWindow.new
			@rest_window.texts = [[_("ボーナス"), ""]]
			@rest_window.make_surface(@main_window.width, 1)
			@rest_window.dock_beside(@main_window, :bottom, 0)
			@max_bonus = 4
			@rest_bonus = @max_bonus
			@default_abilities = {}
			ABILITY_NAMES.each do |name|
				@default_abilities[name] = @member.get_ability_base(name)
			end
			
			@finishing_window = TextWindow.new
			@finishing_window.align = AL_CENTER
			@finishing_window.make_surface(_('決定キーで確定')).update
			@finishing_window.dock_beside(@rest_window, :bottom_right)

			self.update_sequence

			$windows = [DESCRIPTION_WINDOW, DATA_WINDOW, @rest_window, @main_window]
			
			self.on_change

		end
		
		def update_sequence
			ABILITY_NAMES.each_index do |i|
				base = @member.get_ability_base(ABILITY_NAMES[i])
				@main_window.select_items[i].right_caption = base
				@main_window.select_items[i].right_color =
					(base > @default_abilities[ABILITY_NAMES[i]] ? ColorTable::GOOD : ColorTable::WHITE)
			end
			@main_window.update

			
			@rest_window.texts[0][1] = "#{@rest_bonus.to_s}/ #{@max_bonus.to_s}"
			@rest_window.update
			
			if @rest_bonus == 0 then
				@finishing_window.show
				@main_window.show
			else
				@finishing_window.hide
			end
			
			@main_window.silent = true
			
			
		end
		
		def on_leave(to)
			@rest_window = nil
		end
		
		
		def on_change
			id = @main_window.current_id
			case id
			when STR
				text = _("武器攻撃のダメージに影響")
			when TEC
				text = _("武器攻撃の命中率などに影響")
			when AGL
				text = _("回避率、行動の早さに影響")
			when WIL
				text = _("術効果の安定、弓矢のダメージなどに影響")
			when PSY
				text = _("術の威力、最大MPなどに影響")

			end
			
			DESCRIPTION_WINDOW.text = "#{text}"
			DESCRIPTION_WINDOW.update
		end
		
		def inc(ability_id)
			if @rest_bonus >= 1 then
				@member.bonus_points[ability_id] += 1
				@rest_bonus -= 1
				self.update_sequence
				return true
			else
				return false
			end
		end
		
		def dec(ability_id)
			if @rest_bonus < @max_bonus then
				if @member.get_ability_base(ability_id) > @default_abilities[ability_id] then
					@member.bonus_points[ability_id] -= 1
					@rest_bonus += 1
					self.update_sequence
					return true
				end
			end
			return false
		end

		def on_left_key
			SE.cursor_move
			self.dec(@main_window.current_id) if @main_window.current_id
		end
		
		def on_right_key
			SE.cursor_move
			self.inc(@main_window.current_id) if @main_window.current_id
		end
	
		def on_select(id)
			return unless id
			
			if @rest_bonus == 0 then
				SE.equip
				GS.members << @member
				GS.bar_member_ids << (GS.members.size - 1)
				
				if @inherited_member_id then
					inherited_member = GS.members[@inherited_member_id]
					@member.unequip_all_items
					@member.gold = inherited_member.gold
					@member.items = inherited_member.items
					@member.inherited_member_ids = [@inherited_member_id] + inherited_member.inherited_member_ids
					@member.mastery = inherited_member.mastery
					if @member.spell_caster? and inherited_member.spell_caster? then
						@member.spells = inherited_member.spells.slice(0...(@member.spell_max))
					end
					@member.spell_learning = inherited_member.spell_learning 

					
					GS.party.member_ids.delete(@inherited_member_id)
					GS.bar_member_ids.delete(@inherited_member_id)
					inherited_member.existing = false
					inherited_member.profiles[MPT::LostWeek] = GS.week
					
					Game.save(FQ_BIG_CHANGE, "#{inherited_member}を継承した新規キャラクター#{@member.name}の登録")
					
					message(_("%{member}は%{inherited}の魂を受け継ぎ、新たな冒険者となりました\n酒場で仲間に加えることができます").evaluate(:member => @member.name, :inherited => GS.members[@inherited_member_id].name))
				else
					Game.save(FQ_BIG_CHANGE, "新規キャラクター#{@member.name}の登録")
					message(_("%{member}を冒険者として登録しました\n酒場で仲間に加えることができます").evaluate(:member => @member.name))
				end
				BGM.play(:Town)
				Phase.change(GuildMenuPhase.new)
								
			else
				SE.cursor_move
				self.inc(id)
			end
		
		end
		
		def on_cancel
			id = @main_window.current_id
			return unless id

			if @rest_bonus == @max_bonus then
				SE.cancel
				DATA_WINDOW.texts[2][1] = nil
				Phase.change(CharacterClassSelectPhase.new(@inherited_member_id, @member.name, @age))
			else
				SE.cursor_move
				self.dec(id)
			end
			
			
		end

	end
	


	class CharacterDeletePhase < Phase
		include BackablePhase
		def on_enter(from)
			super
			@member_window = OtherMemberWindow.new
			$windows = [PARTY_WINDOW, WARNING_WINDOW, @member_window]
			@member_window.make_surface(8).update(GS.bar_member_ids.map{|x| GS.members[x]}).reset_index.warp
			width = Game.regular_ttf.text_size(_('所持品を全て整理してください'))[0] + PADDING * 2
			WARNING_WINDOW.make_surface(width).dock_beside(@member_window, :bottom)
			WARNING_WINDOW.right = @member_window.right
			
			self.on_change
		end
		
		def on_leave(to)
			@member_window = nil
		end
		
		def on_change

			@member_window.select_items.each do |item|
				member = @member_window.members[item.id]
				unless member.items.empty? then
					item.disable(_('所持品を全て整理してください'))
				end
			end
			
			@member_window.update
			WARNING_WINDOW.update(@member_window.current_item)
			
		end
		
		def on_cancel
			Phase.change(GuildMenuPhase.new)
			SELECT_WINDOW.set(:delete).warp
		end
		
		def on_select(id)
			
			member = @member_window.members[id]
			return unless member
			
			if Game.ask(_("本当に%{member}の登録を抹消してもよろしいですか？\n（抹消したキャラクターは二度と戻ってきません）").evaluate(:member => member.name), :default => :no) then
				member_id = GS.members.index(member)
				GS.bar_member_ids.delete(member_id)
				GS.members[member_id] = nil
				Game.save(FQ_BIG_CHANGE, "キャラクター#{member.name}の削除")
				@member_window.update
				
				message(_("#{member.name}の登録は抹消されました").evaluate(:member => member.name))
				Phase.change(CharacterDeletePhase.new)
			end
			
		end
	end








	class TownOrderChangePhase < Phase
		include OrderChangePhase
		
		def on_enter(from)
			super
			@new_order_window.show
			@old_order_window.show
			
		end
		
		def finish
			super
			Game.save(FQ_CHANGE, '隊列変更')

		end
	end


	
	
	
	
	class InnMenuPhase < Phase
	
		def on_enter(from)
			super
			BGM.fade_out
			
			
			select_items = []
			columns = []
			columns << ColumnItem.new("ROOM", [], 160, AL_LEFT)
			columns << ColumnItem.new("HEALING", [], 60, AL_CENTER)
			columns << ColumnItem.new("EX", [], 60, AL_CENTER)
			columns << ColumnItem.new("FEE", [], 40, AL_RIGHT)
			select_items << SelectItem.new(:stable, _("馬小屋(1)"), SDL::Key::K1)
			select_items << SelectItem.new(:standard, _("普通の部屋(2)"), SDL::Key::K2)
			select_items << SelectItem.new(:large, _("広々とした部屋(3)"), SDL::Key::K3)
			select_items << SelectItem.new(:royal, _("豪華な部屋(4)"), SDL::Key::K4)
			select_items << SelectItem.new(:cancel, _("キャンセル")) if $section == TOWN
			
			@fee_cache = {}
			select_items.each_index do |i|
				id = select_items[i].id
				next if id == :cancel
				columns[1].captions << sprintf("%d%%", INN_HEALING[id] * 100)
				fee = 0
				GS.party.alive_members.each do |member|
					fee += Calc.inn_fee(id, member)
				end
				columns[3].captions << fee
				@fee_cache[id] = fee
				select_items[i].disable if GS.party.gold < fee
			end

			@main_window = MultiColumnWindow.new.make_surface(500, select_items.size).centering.reset_index.warp
			@main_window.select_items = select_items
			@main_window.columns = columns
			@main_window.silent = true
			@main_window.update


			
			INFORMATION_WINDOW.text = _('どこで寝る？')
			INFORMATION_WINDOW.make_surface(120).dock_beside(@main_window, :top)
			on_change
			$windows = [PARTY_WINDOW, INFORMATION_WINDOW, @main_window]
		end
		
		
		def on_change
			super
			item = @main_window.current_item
			if not item.id == :cancel and item.enabled? then
				columns = []
				fees = GS.party.allocate_fees(@fee_cache[item.id])
				captions = fees.map{|x| (x >= 1 ? "-#{x}" : '')}
			else
				captions = []
			end
			
			PARTY_WINDOW.update([ColumnItem.new(s_("ColumnCaption|FEE"), captions, 50, AL_RIGHT, 10)])
		end
		
		
		def on_select(id)
			case @main_window.current_id
			when :stable
				SE.select
			when :cancel
				SE.cancel
			else
				SE.coin
			end
				
			if id == :cancel then
				self.on_cancel
			else
				

				GS.party.lose_gold(@fee_cache[id])
				
				# 回復処理
				GS.party.members.each do |member|
					member.hp_max_penalty = 0
					member.recover_hp((member.hp_max * INN_HEALING[id]).to_i)
					member.set_all_mp
					member.update_last_parameters
				end
				GS.bar_members.each do |member|
					member.hp_max_penalty = 0
					member.recover_hp((member.hp_max * INN_HEALING[:stable]).to_i)
					member.set_all_mp
					member.update_last_parameters
				end
				
	
				Phase.change(SleepPhase.new)
			end
			
		end
		
		def on_cancel
			if $section == TOWN then
				Phase.change(TownMenuPhase.new)
			end
		end
		
		def on_leave(to)
			super
			PARTY_WINDOW.update([])
		end
		
	end
	
	
	
	
	class TownGameConfigPhase < GameConfigPhase
		def finish
			super
			Phase.change(GuildMenuPhase.new)
			SELECT_WINDOW.set(:config).warp
		end
	end
	



end
