execute pathogen#infect()
syntax on
set splitright
set splitbelow
set autoindent
set tabstop=2
set history=100
set shiftwidth=2
colorscheme blue
set autoread
set nowrap

let compileMode=0
let inputFile="input.in"
let outputFile="output.out"
let IOMode=0

function Compile()
  :w
	let folder = expand('%:h')
	let grader = folder . "/grader.cpp"
	let main = folder . "/main.cpp"
	let aout = folder . "/a.out"

	call UseConfig()

	if g:compileMode == 1
  	execute	"!g++ -Wall -DHOME -O2 -std=c++11 -o " . aout . " " . grader . " " . main
	else
		execute "!g++ -Wall -DHOME -O2 -std=c++11 -o " . aout . " " . main
	endif
endfunction

function Run()
  let aout = expand('%:h') . "/a.out"
	
	call UseConfig()

	if g:inputFile == "stdin"
		let input = " < " . expand('%:h') . "/input.txt"
	else
		let input = ""
	endif

	let output = " > " . expand('%:h') . "/output.txt"
	execute "!" . aout . input . output
endfunction

function Input()
	call UseConfig()
  if g:IOMode == 1
		let folder = expand('%:h') . "/" . "input.txt"
	else
		let folder = expand('%:h') . "/" . g:inputFile
	endif
	execute "vs " . folder
endfunction

function Output()
	call UseConfig()
	if g:IOMode == 1
		let folder = expand('%:h') . "/" . "output.txt"
	else
		let folder = expand('%:h') . "/" . g:outputFile
  endif
	execute "vs " . folder
endfunction

function Header()
	let folder = expand('%:h') . "/" . expand('%:h:t') . ".h"
	execute "vs " . folder
endfunction

function Grader()
	let folder = expand('%:h') . "/grader.cpp"
	execute "vs " . folder
endfunction

function Main()
	let folder = expand('%:h') . "/main.cpp"
	execute "vs " . folder
endfunction

function Config()
	let folder = expand('%:h') . "/config.vim"
	execute "vs " . folder
endfunction

function Stdout()
	let folder = expand('%:h') . "/output.txt"
	execute "vs " . folder
endfunction

function WriteConfig(compile, input, output, mode)
	let folder = expand('%:h')
	execute "w! " folder . "/config.vim"
	silent execute "redir! >" . folder . "/config.vim"
	silent execute "echo " . "\"let compileMode=" . a:compile . "\""
	silent execute "echo " . "\"" . "let inputFile=" . "\\\"" . expand(a:input) . "\\\"" . "\""
	silent execute "echo " . "\"" . "let outputFile=" . "\\\"" . expand(a:output) . "\\\"" . "\""
	silent execute "echo " . "\"" . "let IOMode=" . expand(a:mode) . "\""
	silent execute "redir END"
endfunction

function UseConfig()
	let folder = expand('%:h')
	execute "source " . folder . "/config.vim"
endfunction

function NewProject(name)
	if isdirectory(expand('%') . "/" . expand(a:name))
		execute "tab new " . expand('%') . "/" . expand(a:name) . "/main.cpp"
		call UseConfig()
	else
		execute "silent !mkdir " . expand('%') . "/" . expand(a:name)
		execute "tab new " . expand('%') . "/" . expand(a:name) . "/main.cpp"
		call WriteConfig(0, a:name . ".in", a:name . ".out", 0)
		call UseConfig()
	endif
endfunction

function ToggleLine()
  if &nu == 1
    set nonu
    set rnu
  elseif &rnu == 1
    set nornu
  else
    set nu
  endif
endfunction

function ToggleCompiler()	
	call UseConfig()
	silent call WriteConfig(1-g:compileMode, g:inputFile, g:outputFile, g:IOMode)
	if g:compileMode == 0
		echo "Toggled batch mode"
	else
		echo "Toggled interactive mode"
	endif
endfunction

function ToggleIO()
	call UseConfig()

	if g:IOMode == 0
		silent call WriteConfig(g:compileMode, "stdin", "stdout", 1)
		echo "stdin/stdout"
	elseif g:IOMode == 1
		silent call WriteConfig(g:compileMode, "input.txt", "output.txt", 2)
		echo "input.txt/output.txt"
	else
		let folder = expand('%:h:t')
		silent call WriteConfig(g:compileMode, folder . ".in", folder . ".out", 0)
		echo folder . ".in/" . folder . ".out"
	endif
endfunction

function CustomIO(input, output)
	call UseConfig()
	silent call WriteConfig(g:compileMode, a:input, a:output, 3)
	echo a:input . "/" . a:output
endfunction

let mapleader = " "

map <leader>s :w<Return>
map <leader>c :call Compile()<Return>
map <leader>r :call Run()<Return>
map <leader>x :!gedit %<Return>
map <leader>q :q<Return>
map <leader>a <Plug>(easymotion-bd-w)
map <leader>f :TExplore<Return>

"" Project shortcuts
map <leader>i :call Input()<Return>
map <leader>o :call Output()<Return>
map <leader>gg :call Grader()<Return>
map <leader>gm :call Main()<Return>
map <leader>gh :call Header()<Return>
map <leader>gc :call Config()<Return>
map <leader><leader> :call Stdout()<Return>
map <leader><S-n> :call NewProject("")<Left><Left>

"" Tab and splits motion shortcuts
map <leader>e gt
map <leader>w gT
map <leader><Left> <C-w>h
map <leader><Right> <C-w>l

"" Toggle shortcuts
map <leader>tl :call ToggleLine()<Return>
map <leader>tc :call ToggleCompiler()<Return>
map <leader>ti :call ToggleIO()<Return>
map <leader>to :call CustomIO("", "")<Left><Left><Left><Left><Left><Left>

inoremap " ""<Left>
inoremap ' ''<Left>
inoremap { {}<Left>
inoremap [ []<Left>
inoremap ( ()<Left>

map <leader>tetris :!bastet<Return>
map <leader>snake :!nsnake<Return>