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.capture_all_keys? then
								curwin.on_key_press(event.sym)
							else
							
								# ショートカット処理
								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
										 	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
							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

