require "prawn"
require "prawn/grouping"
require "prawn/table"
require "pry"

require_relative "spell"
require_relative "spells"

require_relative "condition"
require_relative "conditions"

require_relative "tilt"
require_relative "tilts"

require_relative "primitive_adds"

puts "Shards of Power PDF generator"
class ShardsOfPower
	FONT_SIZE_CHAPTER = 48
	FONT_SIZE_SECTION = 24
	FONT_SIZE_SUBSECTION = 18
	FONT_SIZE_BODY = 10

	attr_accessor :pdf, :number_name, :chapter_name, :chapter_title, :section_name, :spells, :conditions, :tilts

	def start_chapter(num, name)
		@number_name = num
		@chapter_name = name

		@chapter_title = "Chapter #{number_name}: #{chapter_name}"
		puts "Starting #{chapter_title}"

		pdf.start_new_page

		pdf.outline.update do
			puts "\tAdding #{@shards_of_power.chapter_title} on page #{page_number}"
			section(@shards_of_power.chapter_title, :destination => page_number)
		end

		puts "\tSetting font size"
		pdf.font_size FONT_SIZE_CHAPTER
		pdf.font "Abess"
		puts "\tPrinting chapter to document"
		pdf.text "Chapter #{number_name}: #{chapter_name}", :align => :center

		puts "\tRestoring body text"
		pdf.font "Goudy"
		pdf.font_size FONT_SIZE_BODY
	end

	def start_section(section_name)
		puts "Beginning section #{section_name}: "

		@section_name = section_name

		pdf.outline.add_subsection_to(chapter_title) do
			@pdf.outline.section section_name, :destination => @pdf.page_number
		end

		puts "\tSetting font size"
		pdf.font_size FONT_SIZE_SECTION
		pdf.text section_name, :align => :center

		puts "\tRestoring body text"
		pdf.font_size FONT_SIZE_BODY
		pdf.font "Goudy"

	end

	def roll_results(dramatic_failure:, failure:, success:, exceptional_success:)
		pdf.font_size FONT_SIZE_BODY
		pdf.font "Goudy"

		pdf.text "Roll Results", :style => :bold

		pdf.formatted_text [
			{ :text => "Dramatic Failure: ", :styles => [:bold] },
			{ :text => dramatic_failure }
		]

		pdf.formatted_text [
			{ :text => "Failure: ", :styles => [:bold] },
			{ :text => failure }
		]

		pdf.formatted_text [
			{ :text => "Success: ", :styles => [:bold] },
			{ :text => success }
		]

		pdf.formatted_text [
			{ :text => "Exceptional Success: ", :styles => [:bold] },
			{ :text => exceptional_success }
		]
	end

	def generate
		puts "Parsing spells..."
		@spells = Spell.spells
		@conditions = Condition.conditions
		@conditions.sort_by!(&:name)
		@tilts = Tilt.tilts
		@tilts.sort_by!(&:name)

		puts "Creating PDF object..."
		@pdf = Prawn::Document.new(:margin => 0)
		pdf.default_leading 5

		pdf.font_families.update(
			"Goudy"  => {
				:normal => "goudy.ttf",
				:bold   => "goudy-bold.ttf",
				:italic => "goudy-italic.ttf"
			},
			"Abess"  => {
				:normal => "abess.ttf"
			},
			"Lilith" => {
				:normal => "lilith.ttf"
			},
			"Goblin Hand" => {
				:normal => "VTCGoblinHand.ttf",
				:bold   => "VTCGoblinHandBold.ttf",
				:italic => "VTCGoblinHandItalic.ttf"
			}
		)

		pdf.outline.instance_variable_set(:@shards_of_power, self)

		puts "Importing cover..."
		pdf.image("cover.png", :width => 612, :height => 792)
		
		puts "Printing inner cover..."
		pdf.start_new_page(:margin => 50)

		pdf.font "Abess"
		pdf.font_size 72
		pdf.text "Shards of Power", :align => :center
		puts "\tShards of Power big text..."

		pdf.font "Goudy"
		pdf.font_size 36
		pdf.text "\nA compendium of spells, Conditions, Artifacts, and other interesting tidbits for Mage: the Awakening\n\n", :align => :center
		puts "\tDescription..."

		pdf.font_size 24
		pdf.text "Written by members of the /cofd/ Discord, edited by NEETzsche", :align => :center
		puts "\tMain credit..."
		
		pdf.outline.define do
		end

		start_chapter "One", "Introduction"

		pdf.column_box([0, pdf.cursor], :columns => 2, :width => pdf.bounds.width) do
			pdf.text "Like every supernatural entity in the Chronicles of Darkness, there is a boundless breadth and depth of topics to discuss within them. The Awakened are by no stretch of the imagination an exception to this rule. This book does not dare claim that this will cover all of them, but it does dare to cover the broad strokes on a certain subtopic of the lives of those touched by the Supernal who still reside in the Fallen World: their toolkit.\n\n<b>Mage: the Awakening</b> covered the broadest strokes on Awakened life in general, but there is so much more to the means by which Mages conduct their affairs and pursue their Obsessions that simply is not covered in that volume. There will be yet more that this one fails to consider. However, it is designed to touch on the high level ideas, and dig into some of the specifics for them, leaving you, the reader compelled, and hopefully, inspired as to where to explore next.", :inline_format => true
			
			start_section "Tools Of Awakened Life"
			
			pdf.text "This book is meant to be used as a toolkit. Each of the spells are modular, and for the most part do not operate off of each other. You, as the Storyteller or player, are meant to take the things you find fun, interesting and compelling while leaving the things you find silly, improper, or frustrating behind. This line of thought naturally extends to all of the Conditions, optional Arcana principles, alternative Relinquishment methods, and so on.\n\nThis book was written on a rolling basis by a number of people. It is a compilation, that accumulated over time. It did not get created overnight. As such, by the time you receive this file, there is a good likelihood that it's still in development, which means there might be more up-to-date versions of it, and additionally it may be open to input for your spells, your Artifacts, and your optional rules. The invite code at the time of publication is <b>Cx3JBpB</b>.", :inline_format => true

			start_section "Chapters"

			pdf.text "There are multiple chapters in this book. Each of them covers a specific set of topics.\n\n<b>Chapter One</b> is ithe Introduction. It is what you are reading now. It gives the mission statement, the credits, and a few other key details before you get into the spells and the Conditions.\n\n<b>Chapter Two</b> is the megagrimoire. It is a grimoire of grimoires, much like the book that White Wolf released when they still called themselves that, and is a combined set of spells that the players of this community have mutually agreed are at least somewhat reasonable. Many of us helped each other write these spells. All of their names will be listed in them, alphabetically.\n\n<b>Chapter Three: Conditions & Tilts</b> discusses new Conditions and Tilts that can be imposed by spells, or by other means, such as dramatic failures.", :inline_format => true

			start_section "Credits"

			spell_authors = spells.collect { |spell| spell.authors }.flatten.uniq.sort

			pdf.text "The following users have contributed to Shards of Power, in alphabetical order: #{spell_authors.to_list}"
		end

		start_chapter("Two", "Spells")

		spells.group_by(&:primary_arcanum).sort_by { |arcanum, spells| arcanum }.to_h.each do |arcanum, arcanum_spells|
			arcanum_name = arcanum.to_s.titleize

			puts "Compiling spells for #{arcanum_name}..."

			start_section("#{arcanum_name} Spells")

			pdf.column_box([0, pdf.cursor], :columns => 2, :width => pdf.bounds.width) do
				arcanum_spells.group_by(&arcanum).sort_by { |rating, spells| rating }.to_h.each do |rating, rating_spells|
					rating_title = "#{rating.to_dots} #{Spell::RANKS[rating - 1]} of #{arcanum_name}"
					puts "\tCompiling #{rating_title} spells..."
					pdf.outline.add_subsection_to("#{arcanum_name} Spells") do
						@pdf.outline.section rating_title, :destination => @pdf.page_number
					end

					rating_spells.sort_by! { |spell| spell.name }

					rating_spells.each do |spell|
						puts "\t\tCompiling #{spell.full_title} by #{spell.authors.join(', ')}"
						pdf.outline.add_subsection_to(rating_title) do
							@pdf.outline.section spell.full_title, :destination => @pdf.page_number
						end
						pdf.group do |g|
							if spell == rating_spells.first
								g.font_size FONT_SIZE_SECTION
								g.text rating_title
							end

							spell_ary = [{:text => "#{spell.name} (", :font => "Lilith", :color => "004E6D", :size => FONT_SIZE_SUBSECTION}]

							g.font_size FONT_SIZE_BODY
							previous = false
							spell.arcana.each do |arcanum|
								spell_ary << {:text => ", ", :font => "Lilith", :color => "004E6D", :size => FONT_SIZE_SUBSECTION} if previous
								spell_ary << {:text => arcanum.to_s.titleize, :font => "Lilith", :color => "004E6D", :size => FONT_SIZE_SUBSECTION}
								spell_ary << {:text => spell.send(arcanum).to_dots, :color => "004E6D", :size => FONT_SIZE_SUBSECTION, :character_spacing => -5}
							
								previous = true
							end

							spell_ary << {:text => " )", :font => "Lilith", :styles => [], :color => "004E6D", :size => FONT_SIZE_SUBSECTION, :character_spacing => -3}

							g.formatted_text spell_ary

							g.formatted_text [
								{:text => "Practice: ", :styles => [:bold], :font => "Goudy"},
								{:text => spell.practice, :font => "Goudy"},
							]

							g.formatted_text [
								{:text => "Primary Factor: ", :styles => [:bold], :font => "Goudy"},
								{:text => spell.primary_factor, :font => "Goudy"},
							]

							g.formatted_text [
								{:text => "Withstand: ", :styles => [:bold], :font => "Goudy"},
								{:text => spell.withstand, :font => "Goudy"},
							] if !spell.withstand.nil?

							g.formatted_text [
								{:text => "Cost: ", :styles => [:bold], :font => "Goudy"},
								{:text => spell.cost, :font => "Goudy"},
							] if !spell.cost.nil?

							g.formatted_text [
								{:text => "Suggested Rote Skills: ", :styles => [:bold], :font => "Goudy"},
								{:text => spell.suggested_rote_skills.join(', '), :font => "Goudy"},
							]

							g.formatted_text [
								{:text => spell.authors.length == 1 ? "Author: " : "Authors: ", :styles => [:bold], :font => "Goudy"},
								{:text => spell.authors.join(', '), :font => "Goudy"},
							]

							g.text spell.rules_text, :inline_format => true

							spell.reaches.each do |reach|
								reach_cost = mana_cost = reach_rules = nil
								if reach.size == 3
									g.formatted_text [
										{:text => "+#{reach[0]} Reach, #{reach[1]} Mana: ", :styles => [:bold], :font => "Goudy"},
										{:text => reach[2], :font => "Goudy"},
									]
								else
									g.formatted_text [
										{:text => "+#{reach[0]} Reach: ", :styles => [:bold], :font => "Goudy"},
										{:text => reach[1], :font => "Goudy"},
									]
								end
							end

							spell.adds.each do |add|
								g.formatted_text [
									{:text => "#{add[:verb] ? add[:verb] : "Add"} #{add[:arcana].collect { |arcanum, rating| [arcanum, rating].to_arcanum_with_dots }.to_list(:separator => add[:separator])}: ", :styles => [:bold], :font => "Goudy"},
									{:text => add[:effect], :font => "Goudy"},
								]
							end
						end
					end
				end
			end

			pdf.start_new_page
		end

		start_chapter "Three", "Conditions & Tilts"

		start_section "Conditions"

		puts "Compiling Conditions..."

		pdf.column_box([0, pdf.cursor], :columns => 2, :width => pdf.bounds.width) do
			conditions.each do |condition|
				puts "\tCompiling #{condition.name}..."
				pdf.outline.add_subsection_to("Conditions") do
					@pdf.outline.section condition.name, :destination => @pdf.page_number
				end

				pdf.image "conditionbox.png", :position => :center
				pdf.move_up 30

				pdf.font "Goblin Hand"
				pdf.font_size FONT_SIZE_SUBSECTION
				pdf.fill_color "FFFFFF"
				pdf.text condition.name, :align => :center

				pdf.move_down 10
				pdf.font "Goudy"
				pdf.fill_color "000000"
				pdf.font_size FONT_SIZE_BODY

				pdf.text condition.rules_text, :inline_format => true
				pdf.text "<b>Possible Sources:</b> #{condition.possible_sources}", :inline_format => true if condition.possible_sources
				pdf.text "<b>Resolution:</b> #{condition.resolution}", :inline_format => true
				pdf.text "<b>Beat:</b> #{condition.beat}", :inline_format => true
				pdf.text "<b>#{condition.authors.size > 1 ? "Authors" : "Author"}:</b> #{condition.authors.to_list}", :inline_format => true

			end
		end

		start_section "Tilts"

		puts "Compiling Tilts..."

		pdf.column_box([0, pdf.cursor], :columns => 2, :width => pdf.bounds.width) do
			tilts.each do |tilt|
				puts "\tCompiling #{tilt.full_title}..."
				pdf.outline.add_subsection_to("Tilts") do
					@pdf.outline.section tilt.full_title, :destination => @pdf.page_number
				end

				pdf.image "conditionbox.png", :position => :center

				pdf.font "Goblin Hand"
				pdf.fill_color "FFFFFF"
				pdf.font_size FONT_SIZE_SUBSECTION
				if tilt.environmental?
					pdf.move_up 35
					pdf.text tilt.name, :align => :center
					pdf.font_size FONT_SIZE_BODY
					pdf.text "(Environmental)", :align => :center
				else
					pdf.move_up 30
					pdf.text tilt.name, :align => :center
				end
				
				

				pdf.move_down 10
				pdf.font "Goudy"
				pdf.fill_color "000000"
				pdf.font_size FONT_SIZE_BODY

				pdf.text tilt.rules_text, :inline_format => true
				pdf.text "<b>Effect:</b> #{tilt.effect}", :inline_format => true
				pdf.text "<b>Causing the Tilt:</b> #{tilt.causing}", :inline_format => true
				pdf.text "<b>Ending the Tilt:</b> #{tilt.ending}", :inline_format => true
				pdf.text "<b>#{tilt.authors.size > 1 ? "Authors" : "Author"}:</b> #{tilt.authors.to_list}", :inline_format => true

			end
		end

		pdf.render_file("shards_of_power.pdf")
	end
end

shards_of_power = ShardsOfPower.new
shards_of_power.generate