--===================================================
--
--				GHM_CustomDD
--  			GHM_CustomDD.lua
--
--	          (description)
--
-- 	  (c)2013 The Gryphonheart Team
--			All rights reserved
--===================================================

local count = 1;
local info; -- Placed here to use less memory for dd initialization
function GHM_CustomDD(parent, main, profile)
    local frame = CreateFrame("Frame", "GHM_CustomDD" .. count, parent,"GHM_CustomDD_Template"); -- Create the frame from the xml template
    count = count + 1; -- Increment the counter to give the next frame of this type a unique name

    -- Initialize variables and reference objects
	local label = _G[frame:GetName().."Label"];
	local area = _G[frame:GetName().."Area"];
	local ddFrame = _G[area:GetName().."DD"];
	local ddLabel = _G[ ddFrame:GetName().."TextLabel"];
	ddFrame:SetPoint("TOPLEFT",area,"TOPLEFT",0,0);

	local returnIndex = profile.returnIndex;
	local value,index;

	-- Set the label

    label:SetText(profile.text or "");

	local OnSelect = profile.OnSelect;

    -- Help functions and further setup
    -- All help functions and any further setup needed goes here

	local GetData = function()
		if type(profile.dataFunc) == "function" then
			return profile.dataFunc() or {};
		elseif type(profile.data) == "table" then
			return profile.data;
		elseif type(frame.dataFunc) == "function" then
			return frame.dataFunc() or {};
		elseif type(frame.data) == "table" then
			return frame.data;
		end
		return {};
	end

    -- Position the frame

	if profile.width then
		ddFrame:SetWidth(profile.width);
		frame:SetWidth(profile.width+6);
		_G[ddFrame:GetName() .. "Middle"]:SetWidth(profile.width - 40);
	else
		ddFrame:SetWidth(120);
		frame:SetWidth(120+6);
	end
	frame:SetHeight(ddFrame:GetHeight()+label:GetHeight()+5);

    GHM_FramePositioning(frame,profile,parent);

	-- Drop down initialize

	local Force1;

	UIDropDownMenu_Initialize(ddFrame, function(self)
		local t = GetData();
		if type(t) == "table" then
			for i = 1,#t do
				local text;
				if type(t[i]) == "table" then
					text = t[i].text;
				else
					text = t[i];
				end
				info = {};
				info.text = text;
				info.value = i;
				info.owner = self;
				info.notCheckable = true;
				info.func = function(self)
					local text;
					local returnValue;
					if type(t[self.value]) == "table" then
						text = t[self.value].text;
						returnValue = t[self.value].value;
					else
						text = t[self.value];
					end

					if returnIndex == true then
						Force1(i)
					elseif returnValue then
						Force1(returnValue)
					else
						Force1(text);
					end
				end;
				UIDropDownMenu_AddButton(info);
			end
		end
	end);

    -- Public functions
    local varAttFrame;

    Force1 = function(data)
        -- Set the value and ui to 'data', evt using help functions
		if returnIndex then
			index = data;
			value = GetData()[index];
		else
			local t = GetData();
			index = 1;
			for i=1,#(t) do
				if t[i] == data then
					index = i;
					break;
				end
			end
			value = data;
		end
		ddLabel:SetText(value);
		if OnSelect then
			OnSelect(index);
		end
    end

    local Force2 = function(inputType, inputValue)
        if (inputType == "attribute" or inputType == "variable") and varAttFrame then -- Handles input to var/Att frame
            varAttFrame:SetValue(inputType, inputValue);

        else -- static
            varAttFrame:Clear();
            Force1(inputValue);
        end
    end

    frame.Force = function(self, ...) -- Calls Force1 or Force2 depending on the number of inputs. Either Force(value) or Force(Type,value)
        if self ~= frame then return frame.Force(frame, self, ...); end
        local numInput = #({ ... });

        if numInput == 1 then
            Force1(...);
        elseif numInput == 2 then
            Force2(...);
        end
    end

    frame.Clear = function(self)
        -- Clear the value / ui to a default state
		local t = GetData();
		value = t[1];
		index = 1;
		ddLabel:SetText(value);
		if OnSelect then
			OnSelect(1);
		end
    end


    frame.EnableVariableAttributeInput = function(self, scriptingEnv, item)
        if not (varAttFrame) then
            varAttFrame = GHM_VarAttInput(frame, area, frame:GetWidth());
            frame:SetHeight(frame:GetHeight());
        end
        varAttFrame:EnableVariableAttributeInput(scriptingEnv, item, profile.outputOnly)
    end

    frame.GetValue = function(self) -- Get the current value
        if (varAttFrame and not (varAttFrame:IsStaticTabShown())) then
            return varAttFrame:GetValue();
        else
            if returnIndex then
				return index;
			end
			return value;
        end
    end


    -- Trigger evt onLoad function
    if type(profile.OnLoad) == "function" then
        profile.OnLoad(frame);
    end

    frame.Clear();
    frame:Show();
    return frame;
end

