/*
  ==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions"
   Copyright 2004-6 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================
*/

#include "../../../../juce_core/basics/juce_StandardHeader.h"

BEGIN_JUCE_NAMESPACE


#include "juce_DrawablePath.h"
#include "../brushes/juce_GradientBrush.h"


//==============================================================================
DrawablePath::DrawablePath (const XmlElement* /*xml*/)
    : fillColour (Colours::black),
      strokeType (0.0f),
      isGradient (false)
{
}

DrawablePath::~DrawablePath()
{
}

//==============================================================================
void DrawablePath::setPath (const Path& newPath)
{
    path = newPath;
    updateOutline();
}

void DrawablePath::setSolidFill (const Colour& newColour)
{
    isGradient = false;
    fillColour = newColour;
}

void DrawablePath::setGradientFill (const ColourGradient& gradient_)
{
    isGradient = true;
    gradient = gradient_;
}

void DrawablePath::setOutline (const float thickness, const Colour& colour)
{
    strokeType = PathStrokeType (thickness);
    outlineColour = colour;
    updateOutline();
}

void DrawablePath::setOutline (const PathStrokeType& strokeType_, const Colour& colour)
{
    strokeType = strokeType_;
    outlineColour = colour;
    updateOutline();
}


//==============================================================================
void DrawablePath::draw (Graphics& g, const AffineTransform& transform) const
{
    const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later
    const float currentOpacity = oldColour.getFloatAlpha();

    if (isGradient)
    {
        ColourGradient grad (gradient);

        transform.transformPoint (grad.x1, grad.y1);
        transform.transformPoint (grad.x2, grad.y2);

        grad.multiplyOpacity (currentOpacity);

        GradientBrush gb (grad);

        g.setBrush (&gb);
        g.fillPath (path, transform);
    }
    else
    {
        g.setColour (fillColour.withMultipliedAlpha (currentOpacity));
        g.fillPath (path, transform);
    }

    if (strokeType.getStrokeThickness() > 0.0f && ! outlineColour.isTransparent())
    {
        g.setColour (outlineColour.withMultipliedAlpha (currentOpacity));
        g.fillPath (outline, transform);
    }

    g.setColour (oldColour);
}

void DrawablePath::updateOutline()
{
    outline.clear();

    // (this will do nothing if the stroke width is <= 0)
    strokeType.createStrokedPath (outline, path);
}

void DrawablePath::getBounds (float& x, float& y, float& width, float& height) const
{
    if (strokeType.getStrokeThickness() > 0.0f)
        outline.getBounds (x, y, width, height);
    else
        path.getBounds (x, y, width, height);
}

bool DrawablePath::hitTest (float x, float y) const
{
    return path.contains (x, y)
        || outline.contains (x, y);
}

Drawable* DrawablePath::createCopy() const
{
    DrawablePath* const dp = new DrawablePath();

    dp->path = path;
    dp->fillColour = fillColour;
    dp->gradient = gradient;
    dp->outlineColour = outlineColour;
    dp->strokeType = strokeType;
    dp->isGradient = isGradient;
    dp->updateOutline();

    return dp;
}

XmlElement* DrawablePath::toXml() const
{
    return 0; //xxx
}

END_JUCE_NAMESPACE
