-- Copyright (C) 2010 Tyson Brown
-- 
-- This file is part QuestHelper2, an AddOn for World of Warcraft.
-- 
-- QuestHelper2 is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- 
-- QuestHelper2 is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
-- 
-- You should have received a copy of the GNU General Public License
-- along with QuestHelper2. If not, see <http://www.gnu.org/licenses/>.

if LibDebug then LibDebug() end
local shared = select(2, ...)

local functions = {}

shared.meta.AchievementData = { __index = functions, name="AchievementData" }

function shared.createAchievementData(id)
  return setmetatable({
    finish = shared.createLocationList(),
    criteria = {}
  }, shared.meta.AchievementData)
end

function functions:addFinishLocation(...)
  self.finish:addLocation(...)
  
  shared.dirtyAchievementData(self)
end

local function getCriteriaData(self, criteria)
  local criteria_data = self.criteria[criteria]
  
  if not criteria_data then
    criteria_data = {
      location = shared.createLocationList(),
      assets = {},
    }
    self.criteria[criteria] = criteria_data
  end
  
  return criteria_data
end

function functions:addCriteriaLocation(criteria, ...)
  criteria = getCriteriaData(self, criteria)
  criteria.location:addLocation(...)
  
  shared.dirtyAchievementData(self)
end

function functions:addCriteriaAsset(criteria, asset, asset_type, asset_weight)
  criteria = getCriteriaData(self, criteria)
  local assets = criteria.assets[asset_type]
  
  if not assets then
    assets = {}
    criteria.assets[asset_type] = assets
  end
  
  assets[asset] = (assets[asset] or 0)+(asset_weight or 1)
  
  shared.dirtyAchievementData(self)
end

local function locationsWeight(location_list)
  local weight = 0
  
  if location_list then
    for a, l, x, y, ex, ey, w in location_list:iterate() do
      weight = weight + w
    end
  end
  
  return weight
end

function functions:estimateWeight()
  local weight = self.finish:weight()
  
  for i, criteria_data in pairs(self.criteria) do
    weight = math.min(weight, criteria_data.location:weight())
  end
  
  return weight
end

function functions:merge(achievement)
  if self ~= achievement then
    self.finish:merge(achievement.finish)
    
    for criteria, criteria_data in pairs(achievement.criteria) do
      local local_criteria_data = getCriteriaData(self, criteria)
      
      local_criteria_data.location:merge(criteria_data.location)
      
      if criteria_data.assets then
        for asset_type, asset_map in pairs(criteria_data.assets) do
          for asset_id, asset_weight in pairs(asset_map) do
            local assets = local_criteria_data.assets[asset_type]
            
            if not assets then
              assets = {}
              local_criteria_data.assets[asset_type] = assets
            end
            
            assets[asset_id] = (assets[asset_id] or 0)+asset_weight
          end
        end
      end
    end
  end
end

function functions:reduceToEssentials()
  self.finish:pruneLocations(8)
  
  for i, criteria_data in pairs(self.criteria) do
    criteria_data.assets = nil
    criteria_data.location:pruneLocations(8)
  end
end
