1/*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21#ifndef StepRange_h
22#define StepRange_h
23
24#include "Decimal.h"
25#include <wtf/Forward.h>
26#include <wtf/Noncopyable.h>
27
28namespace WebCore {
29
30class HTMLInputElement;
31
32enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
33
34class StepRange {
35public:
36    enum StepValueShouldBe {
37        StepValueShouldBeReal,
38        ParsedStepValueShouldBeInteger,
39        ScaledStepValueShouldBeInteger,
40    };
41
42    struct StepDescription {
43        WTF_MAKE_FAST_ALLOCATED;
44    public:
45        int defaultStep;
46        int defaultStepBase;
47        int stepScaleFactor;
48        StepValueShouldBe stepValueShouldBe;
49
50        StepDescription(int defaultStep, int defaultStepBase, int stepScaleFactor, StepValueShouldBe stepValueShouldBe = StepValueShouldBeReal)
51            : defaultStep(defaultStep)
52            , defaultStepBase(defaultStepBase)
53            , stepScaleFactor(stepScaleFactor)
54            , stepValueShouldBe(stepValueShouldBe)
55        {
56        }
57
58        StepDescription()
59            : defaultStep(1)
60            , defaultStepBase(0)
61            , stepScaleFactor(1)
62            , stepValueShouldBe(StepValueShouldBeReal)
63        {
64        }
65
66        Decimal defaultValue() const
67        {
68            return defaultStep * stepScaleFactor;
69        }
70    };
71
72    StepRange();
73    StepRange(const StepRange&);
74    StepRange(const Decimal& stepBase, const Decimal& minimum, const Decimal& maximum, const Decimal& step, const StepDescription&);
75    Decimal acceptableError() const;
76    Decimal alignValueForStep(const Decimal& currentValue, const Decimal& newValue) const;
77    Decimal clampValue(const Decimal& value) const;
78    bool hasStep() const { return m_hasStep; }
79    Decimal maximum() const { return m_maximum; }
80    Decimal minimum() const { return m_minimum; }
81    static Decimal parseStep(AnyStepHandling, const StepDescription&, const String&);
82    Decimal step() const { return m_step; }
83    Decimal stepBase() const { return m_stepBase; }
84    int stepScaleFactor() const { return m_stepDescription.stepScaleFactor; }
85    bool stepMismatch(const Decimal&) const;
86
87    // Clamp the middle value according to the step
88    Decimal defaultValue() const
89    {
90        return clampValue((m_minimum + m_maximum) / 2);
91    }
92
93    // Map value into 0-1 range
94    Decimal proportionFromValue(const Decimal& value) const
95    {
96        if (m_minimum == m_maximum)
97            return 0;
98
99        return (value - m_minimum) / (m_maximum - m_minimum);
100    }
101
102    // Map from 0-1 range to value
103    Decimal valueFromProportion(const Decimal& proportion) const
104    {
105        return m_minimum + proportion * (m_maximum - m_minimum);
106    }
107
108private:
109    StepRange& operator =(const StepRange&);
110    Decimal roundByStep(const Decimal& value, const Decimal& base) const;
111
112    const Decimal m_maximum; // maximum must be >= minimum.
113    const Decimal m_minimum;
114    const Decimal m_step;
115    const Decimal m_stepBase;
116    const StepDescription m_stepDescription;
117    const bool m_hasStep;
118};
119
120}
121
122#endif // StepRange_h
123