/*
 * Copyright (C) 2013 Apple Inc. All rights reserved.
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <wtf/text/StringView.h>

namespace WebCore {

const int UninitializedDescriptor = -1;
const float DefaultDensityValue = 1.0;

class DescriptorParsingResult {
public:
    DescriptorParsingResult()
        : m_density(UninitializedDescriptor)
        , m_resourceWidth(UninitializedDescriptor)
        , m_resourceHeight(UninitializedDescriptor)
    {
    }

    bool hasDensity() const { return m_density >= 0; }
    bool hasWidth() const { return m_resourceWidth >= 0; }
    bool hasHeight() const { return m_resourceHeight >= 0; }

    float density() const { ASSERT(hasDensity()); return m_density; }
    unsigned resourceWidth() const { ASSERT(hasWidth()); return m_resourceWidth; }
    unsigned resourceHeight() const { ASSERT(hasHeight()); return m_resourceHeight; }

    void setResourceWidth(int width) { ASSERT(width >= 0); m_resourceWidth = (unsigned)width; }
    void setResourceHeight(int height) { ASSERT(height >= 0); m_resourceHeight = (unsigned)height; }
    void setDensity(float densityToSet) { ASSERT(densityToSet >= 0); m_density = densityToSet; }

private:
    float m_density;
    int m_resourceWidth;
    int m_resourceHeight;
};

struct ImageCandidate {
    enum OriginAttribute {
        SrcsetOrigin,
        SrcOrigin
    };

    ImageCandidate()
        : density(DefaultDensityValue)
        , resourceWidth(UninitializedDescriptor)
        , originAttribute(SrcsetOrigin)
    {
    }

    ImageCandidate(StringView source, const DescriptorParsingResult& result, OriginAttribute originAttribute)
        : string(source)
        , density(result.hasDensity() ? result.density() : UninitializedDescriptor)
        , resourceWidth(result.hasWidth() ? result.resourceWidth() : UninitializedDescriptor)
        , originAttribute(originAttribute)
    {
    }

    bool srcOrigin() const
    {
        return (originAttribute == SrcOrigin);
    }
    
    bool isEmpty() const
    {
        return string.isEmpty();
    }

    StringView string;
    float density;
    int resourceWidth;
    OriginAttribute originAttribute;
};

ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const AtomString& srcAttribute, const AtomString& srcsetAttribute, float sourceSize);

Vector<ImageCandidate> parseImageCandidatesFromSrcsetAttribute(StringView attribute);

} // namespace WebCore
