module DarkHall
	
	class << Game
		def operation_loop(title = "NamelessLoop")
			$operation_loop_stack << title
			result = catch(:exit_operation_loop){
				loop do
					while event = SDL::Event2.poll
						SDL::Key.scan
						curwin = Game.current_window
						case event
						when SDL::Event2::Quit
							Game.quit
						when SDL::Event2::KeyDown
							# ショートカット処理
							if curwin.kind_of?(SelectableWindow) then
								if Input.ctrl_pressed? then
									index = curwin.select_items.map{|x| x.keycode if x and x.need_ctrl_key?}.index(event.sym)
								else
									index = curwin.select_items.map{|x| x.keycode if x and not x.need_ctrl_key?}.index(event.sym)
								end
								
								if index then
									curwin.change(index)
									Game.wait(2)
									unless curwin.current_item.disabled? then
										SE.select
									 	curwin.on_select(curwin.select_items[index].id)
									end
								end
							end
				
						
							case event.sym
							when SDL::Key::F1, SDL::Key::F2, SDL::Key::F3, SDL::Key::F4
								if Input.alt_pressed? and event.sym == SDL::Key::F4 then
									Game.quit
								else
									Input.system_menu
								end
							when SDL::Key::UP
								Input.up
				
							when SDL::Key::DOWN
								Input.down
				
							when SDL::Key::LEFT
								Input.left
							when SDL::Key::RIGHT
								Input.right
				
							when SDL::Key::PAGEUP
								Input.page_up
				
							when SDL::Key::PAGEDOWN
								Input.page_down
				
							when SDL::Key::HOME
								Input.home
							when SDL::Key::END
								Input.end
							when SDL::Key::LSHIFT, SDL::Key::RSHIFT
								Input.shift_down
							when SDL::Key::LCTRL, SDL::Key::RCTRL
								Input.ctrl_down
				
							when SDL::Key::RETURN, SDL::Key::Z, SDL::Key::SPACE
								Input.enter
							when SDL::Key::ESCAPE, SDL::Key::X, SDL::Key::BACKSPACE
								Input.esc
								
							
							else
								curwin.on_key_press(event.sym)
							end
							
						when SDL::Event2::KeyUp
							case event.sym
							when SDL::Key::LSHIFT, SDL::Key::RSHIFT
								Input.shift_up
							when SDL::Key::LCTRL, SDL::Key::RCTRL
								Input.ctrl_up
							end
							
						when SDL::Event2::MouseMotion
							if GS.game_config.mouse_operation then
	
								# マウスが移動したかどうかの判定
								if ((event.xrel.abs + event.yrel.abs) >= 1) then
									if @mouse_down_x and @mouse_down_y and curwin.kind_of?(DungeonWindow) then
										if event.x - @mouse_down_x > 80 then
											@mouse_down_x, @mouse_down_y = nil, nil
											@drag_input = true
											$phase.on_right_drag
										elsif event.x - @mouse_down_x < -80 then
											@mouse_down_x, @mouse_down_y = nil, nil
											@drag_input = true
											$phase.on_left_drag
										elsif event.y - @mouse_down_y > 80 then
											@mouse_down_x, @mouse_down_y = nil, nil
											@drag_input = true
											$phase.on_down_drag
										end
									elsif curwin.kind_of?(SelectableWindow) then
										curwin.on_mouse_move(event.x, event.y)
									end
								end
							end
							
						when SDL::Event2::MouseButtonDown
							if GS.game_config.mouse_operation then
								case event.button
								when SDL::Mouse::BUTTON_LEFT
									if curwin.kind_of?(DungeonWindow) then
										@mouse_down_x = event.x
										@mouse_down_y = event.y
										@drag_input = false
									else
										@mouse_down_x, @mouse_down_y = nil, nil
										Input.left_click(event.x, event.y)
									end
								when SDL::Mouse::BUTTON_RIGHT
									Input.right_click
								when SDL::Mouse::BUTTON_MIDDLE
									Input.wheel_push
								when 4 # 上ホイール
									Input.wheel_up
								when 5 # 下ホイール
									Input.wheel_down
								end
							end
						when SDL::Event2::MouseButtonUp
							if GS.game_config.mouse_operation and
							event.button == SDL::Mouse::BUTTON_LEFT and
							curwin.kind_of?(DungeonWindow) then
							
								if not @drag_input and @mouse_down_x and @mouse_down_y then
									@mouse_down_x, @mouse_down_y = nil, nil
									Input.left_click(event.x, event.y)
								end
								
							end

						when SDL::Event2::JoyButtonDown
							case event.button
							when GS.game_config.key_assign['Decide']
								Input.enter
							when GS.game_config.key_assign['Cancel']
								Input.esc
							when GS.game_config.key_assign['SystemMenu']
								Input.system_menu
							else
								if event.button == GS.game_config.key_assign['LeftWalk'] && defined?($phase.on_left_walk_key) then
									Input.left_walk
								elsif event.button == GS.game_config.key_assign['RightWalk'] && defined?($phase.on_right_walk_key) then
									Input.right_walk
								elsif event.button == GS.game_config.key_assign['PageUp'] then
									Input.page_up
								elsif event.button == GS.game_config.key_assign['PageDown'] then
									Input.page_down
								elsif event.button == GS.game_config.key_assign['ActionMenu'] then
									Input.shift_down
								end
							end
						when SDL::Event2::JoyAxis
							case event.axis
							when 0
								if event.value >= 20000 then
									Input.right
								elsif event.value <= -20000 then
									Input.left
								end
							when 1
								if event.value >= 20000 then
									Input.down
								elsif event.value <= -20000 then
									Input.up
								end
							end
						end
						
					end
					
					#BGM.on_every_frame
					
					refresh
				
				end
			}
			poped = $operation_loop_stack.pop
			return result
		end
		
	end
end

