package exporter

import (
	"strconv"
	//"fmt"

	"github.com/f0086/toolheim/parser"
	"github.com/jung-kurt/gofpdf"
)

var marker_sign = "X"
var text_color_r = 170
var text_color_g = 0
var text_color_b = 0

var startY = 0
var offsetY = 0

func MakeHeroPage(warband parser.Warband, pdf *gofpdf.Fpdf, newPage bool) {
	if !newPage {
		// add a new page if required
		if startY > 297-60 {
			pdf.AddPage()
			startY = 0
			offsetY = 0
		}
	} else {
		pdf.AddPage()
		startY = 0
		offsetY = 0
	}

	shiftY := 44
	for i, hero := range warband.Heros {
		if i > 0 {
			offsetY = offsetY + shiftY
		}

		// handle multipage henchmen lists
		if offsetY > 297-60 {
			pdf.AddPage()
			offsetY = 0
		}

		// Background
		pdf.SetXY(5, float64(offsetY+5))
		pdf.Image("images/hero.png", 5, 0, 1499*0.133, 295*0.133, true, "", 0, "")

		// Name
		pdf.SetFont("Arial", "B", 12)
		pdf.SetXY(18, float64(offsetY+4))
		pdf.Write(11, hero.Name)

		// Type
		pdf.SetFont("Arial", "", 12)
		pdf.SetXY(18, float64(offsetY+10))
		pdf.Write(11, hero.Type)

		// Stats
		pdf.SetFillColor(255, 0, 0)
		pdf.SetFont("Arial", "", 13)
		pdf.SetFontUnitSize(5)

		pdf.SetXY(6, float64(offsetY+24))
		if len(hero.Stats.Movement) > 1 {
			pdf.SetX(3)
		}
		pdf.Write(11, hero.Stats.Movement)
		pdf.SetX(13)
		pdf.Write(11, strconv.Itoa(hero.Stats.WeaponSkill))
		pdf.SetX(20)
		pdf.Write(11, strconv.Itoa(hero.Stats.BallisticSkill))
		pdf.SetX(27)
		pdf.Write(11, strconv.Itoa(hero.Stats.Strength))
		pdf.SetX(33)
		pdf.Write(11, strconv.Itoa(hero.Stats.Toughness))
		pdf.SetX(40)
		pdf.Write(11, strconv.Itoa(hero.Stats.Wounds))
		pdf.SetX(46)
		pdf.Write(11, strconv.Itoa(hero.Stats.Initiative))
		pdf.SetX(53)
		pdf.Write(11, strconv.Itoa(hero.Stats.Attacks))
		pdf.SetX(59.5)
		pdf.Write(11, strconv.Itoa(hero.Stats.Leadership))
		pdf.SetX(66.0)
		pdf.Write(11, hero.Stats.Save)

		// Skill lists
		if hero.BSkillLists.Combat == true {
			pdf.SetFont("Arial", "B", 10)
			pdf.SetXY(7.25, float64(offsetY+21))
			pdf.Write(0, marker_sign)
		}
		if hero.BSkillLists.Shooting == true {
			pdf.SetFont("Arial", "B", 10)
			pdf.SetXY(17.75, float64(offsetY+21))
			pdf.Write(0, marker_sign)
		}
		if hero.BSkillLists.Academic == true {
			pdf.SetFont("Arial", "B", 10)
			pdf.SetXY(28.72, float64(offsetY+21))
			pdf.Write(0, marker_sign)
		}
		if hero.BSkillLists.Strength == true {
			pdf.SetFont("Arial", "B", 10)
			pdf.SetXY(40.5, float64(offsetY+21))
			pdf.Write(0, marker_sign)
		}
		if hero.BSkillLists.Speed == true {
			pdf.SetFont("Arial", "B", 10)
			pdf.SetXY(51.5, float64(offsetY+21))
			pdf.Write(0, marker_sign)
		}
		if hero.BSkillLists.Special == true {
			pdf.SetFont("Arial", "B", 10)
			pdf.SetXY(60.7, float64(offsetY+21))
			pdf.Write(0, marker_sign)
		}

		// Weapons
		if hero.Weapons != nil {
			for w, weapon := range hero.Weapons.List {
				if w == 0 {
					pdf.SetFont("Arial", "B", 10)
				} else {
					pdf.SetFont("Arial", "", 10)
				}
				pdf.SetXY(138, float64(offsetY+7+(w*5)))
				pdf.Write(11, weapon)
			}
		}

		// Armour
		pdf.SetFont("Arial", "", 10)
		if hero.Armour != nil {
			for j, armour := range hero.Armour.List {
				pdf.SetXY(168, float64(offsetY+3+(j*5)))
				pdf.Write(11, armour)
			}
		}

		ox := 0
		oy := 0
		if hero.Rules != nil {
			for j, rule := range hero.Rules.List {
				pdf.SetXY(float64(75+ox), float64(offsetY+6+(j*5)+oy))
				pdf.Write(11, rule)
				if j == 3 {
					// start right of the first line after 4th line
					ox = 30
					oy = -20
				}
			}
		}

		if hero.HiredSword {
			// show hired sword marker
			pdf.SetXY(0, float64(offsetY)+38.5)
			pdf.Image("images/hiredsword_marker.png", 6, 0, 421*0.053, 97*0.053, true, "", 0, "")
		}

		// XP
		pdf.SetFont("Arial", "", 20)
		pdf.SetXY(185, float64(offsetY+28))
		pdf.Write(20, strconv.Itoa(hero.Experience))
		y := 0.0
		reduce_x := 0
		for x := 1; x <= hero.Experience; x++ {
			pdf.SetFont("Arial", "B", 10)
			xx := x
			if reduce_x > 0 {
				xx = xx - reduce_x*30
			}
			pdf.SetXY(float64(73+((float64(xx)-1.0)*3.43)), float64(offsetY)+float64(y)*15.0+34.0)
			pdf.Write(0, marker_sign)
			if x == 30 || x == 60 {
				y = y + 0.22
				reduce_x = reduce_x + 1
			}
		}

	}

	offsetY = offsetY + shiftY

}

func MakeHenchmenPage(warband parser.Warband, pdf *gofpdf.Fpdf, newPage bool) {

	if !newPage {
		// add a new page if required
		if startY > 297-60 {
			pdf.AddPage()
			startY = 0
			offsetY = 0
		}
	} else {
		pdf.AddPage()
		startY = 0
		offsetY = 0
	}

	shiftY := 34
	for i, henchmen := range warband.HenchmenGroups {
		if i > 0 {
			offsetY = offsetY + shiftY
		}

		// handle multipage henchmen lists
		if offsetY > 297-60 {
			pdf.AddPage()
			offsetY = 0
		}

		// Background
		pdf.SetX(5)
		pdf.SetY(float64(offsetY + 5))
		pdf.Image("images/henchmen.png", 5, 0, 1499*0.133, 218*0.133, true, "", 0, "")

		pdf.SetFont("Arial", "B", 12)
		// Name
		pdf.SetY(float64(offsetY + 4))
		pdf.SetX(18)
		pdf.Write(11, henchmen.Name)

		// Type
		pdf.SetFont("Arial", "", 12)
		pdf.SetY(float64(offsetY + 9))
		pdf.SetX(18)
		pdf.Write(11, henchmen.Type)

		// Number
		pdf.SetFont("Arial", "B", 12)
		pdf.SetY(float64(offsetY + 9))
		pdf.SetX(64)
		pdf.Write(11, strconv.Itoa(henchmen.Number))

		// Stats
		pdf.SetFillColor(255, 0, 0)

		pdf.SetFont("Arial", "", 12)
		pdf.SetFontUnitSize(5)

		pdf.SetY(float64(offsetY + 18))
		pdf.SetX(6)
		if len(henchmen.Stats.Movement) > 1 {
			pdf.SetX(3)
		}
		pdf.Write(11, henchmen.Stats.Movement)
		pdf.SetX(13)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.WeaponSkill))
		pdf.SetX(20)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.BallisticSkill))
		pdf.SetX(27)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.Strength))
		pdf.SetX(33)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.Toughness))
		pdf.SetX(40)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.Wounds))
		pdf.SetX(46)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.Initiative))
		pdf.SetX(53)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.Attacks))
		pdf.SetX(59.5)
		pdf.Write(11, strconv.Itoa(henchmen.Stats.Leadership))
		pdf.SetX(66.0)
		pdf.Write(11, henchmen.Stats.Save)

		// Weapons
		if henchmen.Weapons != nil {
			for w, weapon := range henchmen.Weapons.List {
				if w == 0 {
					pdf.SetFont("Arial", "B", 10)
				} else {
					pdf.SetFont("Arial", "", 10)
				}
				pdf.SetXY(138, float64(offsetY+7+(w*5)))
				pdf.Write(11, weapon)
			}
		}

		// Armour
		pdf.SetFont("Arial", "", 10)
		if henchmen.Armour != nil {
			for j, armour := range henchmen.Armour.List {
				pdf.SetXY(170, float64(offsetY+3+(j*5)))
				pdf.Write(11, armour)
			}
		}

		// Rules
		if henchmen.Rules != nil {
			for j, rule := range henchmen.Rules.List {
				pdf.SetXY(75, float64(offsetY+7+(j*5)))
				pdf.Write(11, rule)
			}
		}

		// XP
		pdf.SetFont("Arial", "", 13)
		pdf.SetXY(190, float64(offsetY+21))
		pdf.Write(20, strconv.Itoa(henchmen.Experience))
		for x := 1; x <= henchmen.Experience; x++ {
			pdf.SetFont("Arial", "B", 12)
			pdf.SetXY(float64(137+((float64(x)-1.0)*3.45)), float64(offsetY)+30.5)
			pdf.Write(0, marker_sign)
		}

	}

}

func MakeStatisticPage(warband parser.Warband, pdf *gofpdf.Fpdf) {

	// Statistic page
	pdf.AddPage()

	startY = 23
	offsetY = 0

	// First page warband heading
	pdf.SetFont("Arial", "B", 28)
	pdf.SetXY(5, 5)
	pdf.Write(11, warband.Warband.Name)
	pdf.SetFont("Arial", "B", 17)
	pdf.SetXY(5, 13)
	pdf.Write(11, warband.Warband.Race)

	offsetY = 23

	// Warband status
	pdf.SetX(5)
	pdf.SetY(float64(offsetY) + 5)
	pdf.Image("images/wb_stats.png", 5, 0, 1499*0.133, 218*0.133, true, "", 0, "")

	// Equipment
	pdf.SetFont("Arial", "", 10)
	oX := 0
	oY := 0
	if warband.Equipment != nil {
		for j, e := range warband.Equipment.List {
			pdf.SetXY(123+float64(oX), float64(offsetY+oY+6+(j*5)))
			pdf.Write(11, e)
			if j == 4 {
				oX = 40
				oY = -25
			}
		}
	}

	pdf.SetFont("Arial", "B", 10)
	pdf.SetXY(55, float64(offsetY)+32.0)
	pdf.Write(0, strconv.Itoa(warband.Rating))

	pdf.SetFont("Arial", "", 10)
	pdf.SetXY(72.5, float64(offsetY)+32.0)
	pdf.SetTextColor(0, 0, 0)
	pdf.Write(0, "Routtest: ")
	pdf.SetFont("Arial", "", 10)
	pdf.SetTextColor(text_color_r, text_color_g, text_color_b)
	pdf.SetXY(95, float64(offsetY)+32.0)
	pdf.Write(0, strconv.Itoa(warband.Routtest))

	pdf.SetFont("Arial", "", 10)
	pdf.SetXY(55, float64(offsetY)+11.25)
	pdf.Write(0, strconv.Itoa(warband.Hero_sum_xp))

	pdf.SetXY(60, float64(offsetY)+11.25)
	pdf.Write(0, "(+"+strconv.Itoa(warband.WarbandAddition_sum)+")")

	pdf.SetFont("Arial", "", 10)
	pdf.SetXY(55, float64(offsetY)+14.75)
	pdf.Write(0, strconv.Itoa(warband.Henchmen_sum_xp))

	pdf.SetFont("Arial", "B", 10)
	pdf.SetXY(22.05, float64(offsetY)+18.0)
	pdf.Write(0, strconv.Itoa(warband.Hero_cnt+warband.Henchmen_cnt+warband.Hiredsword_cnt))
	pdf.SetFont("Arial", "", 10)
	pdf.SetXY(55.0, float64(offsetY)+18.0)
	pdf.Write(0, strconv.Itoa((warband.Hero_cnt+warband.Henchmen_cnt+warband.Hiredsword_cnt)*5))

	pdf.SetFont("Arial", "B", 10)
	pdf.SetXY(32.05, float64(offsetY)+21.25)
	pdf.Write(0, strconv.Itoa(warband.Large_cnt))
	pdf.SetFont("Arial", "", 10)
	pdf.SetXY(55.0, float64(offsetY)+21.25)
	pdf.Write(0, strconv.Itoa((warband.Large_cnt)*20))

	pdf.SetFont("Arial", "B", 10)
	pdf.SetXY(27.05, float64(offsetY)+24.5)
	pdf.Write(0, "( "+strconv.Itoa(warband.Hiredsword_cnt)+" )")
	pdf.SetFont("Arial", "", 10)
	pdf.SetXY(55.0, float64(offsetY)+24.5)
	pdf.Write(0, strconv.Itoa(warband.Hiredsword_sum_xp))

	pdf.SetFont("Arial", "B", 10)
	pdf.SetXY(95, float64(offsetY)+11.25)
	pdf.Write(0, strconv.Itoa(warband.GoldCrowns))

	pdf.SetFont("Arial", "B", 10)
	pdf.SetXY(95, float64(offsetY)+17.75)
	pdf.Write(0, strconv.Itoa(warband.Shards))

	// Campaign info block
	offsetY = offsetY + 40
	pdf.SetXY(5, float64(offsetY))
	pdf.Image("images/campaign.png", 5, 0, 1499*0.133, 218*0.133, true, "", 0, "")

	pdf.SetFont("Arial", "B", 10)
	pdf.SetXY(22, float64(offsetY)+6.25)
	pdf.Write(0, warband.Objective)

	pdf.SetFont("Arial", "", 10)
	pdf.SetXY(147, float64(offsetY)+20.0)
	pdf.Write(0, strconv.Itoa(warband.CampaignPoints))

	row := 0
	for x := 1; x <= warband.CampaignPoints; x++ {
		pdf.SetFont("Arial", "B", 8)
		xx := x - (row * 20)
		pdf.SetXY(float64(130.75+((float64(xx)-1.0)*3.30)), float64(offsetY)+float64(24.4)+float64((float64(row)*float64(2.5))))
		pdf.Write(0, marker_sign)
		if x == 20 {
			row = row + 1
		}
	}

	// Notes block
	offsetY = offsetY + 35
	pdf.SetXY(5, float64(offsetY))
	pdf.Image("images/notes.png", 5, 0, 1499*0.133, 218*0.33, true, "", 0, "")

	pdf.SetFont("Arial", "", 12)
	lines := pdf.SplitLines([]byte(warband.Notes), 195)
	for i := 0; i < len(lines); i++ {
		pdf.SetXY(7.0, float64(offsetY+8+i*8))
		pdf.Write(0, string(lines[i]))
	}

	// the space after
	offsetY = offsetY + 70

	/*
		pdf.SetFont("Arial", "B", 13)
		pdf.SetXY(20, float64(offsetY+21))
		pdf.Write(20, strconv.Itoa(hero_cnt))

		pdf.SetFont("Arial", "B", 13)
		pdf.SetXY(20, float64(offsetY+21))
		pdf.Write(20, strconv.Itoa(len(warband.HenchmenGroups)))

		pdf.SetFont("Arial", "B", 13)
		pdf.SetXY(20, float64(offsetY+21))
		pdf.Write(20, strconv.Itoa(henchmen_cnt))

		offsetY = offsetY + 20
		pdf.SetFont("Arial", "B", 13)
		pdf.SetXY(20, float64(offsetY+21))
		pdf.Write(20, strconv.Itoa(hero_cnt+henchmen_cnt))
	*/

}

func MakePDF(warband parser.Warband, multiPage bool) {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.SetTextColor(text_color_r, text_color_g, text_color_b)

	MakeStatisticPage(warband, pdf)
	MakeHeroPage(warband, pdf, multiPage)
	MakeHenchmenPage(warband, pdf, multiPage)

	// TODO: Make output name variable or use name of the input file
	err := pdf.OutputFileAndClose("warband-roaster.pdf")

	if err != nil {
		panic(err)
	}
}
