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 "platform/Decimal.h"
25#include "wtf/Forward.h"
26
27namespace blink {
28
29class HTMLInputElement;
30
31enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
32
33class StepRange {
34public:
35    enum StepValueShouldBe {
36        StepValueShouldBeReal,
37        ParsedStepValueShouldBeInteger,
38        ScaledStepValueShouldBeInteger,
39    };
40
41    struct StepDescription {
42        WTF_MAKE_FAST_ALLOCATED;
43    public:
44        int defaultStep;
45        int defaultStepBase;
46        int stepScaleFactor;
47        StepValueShouldBe stepValueShouldBe;
48
49        StepDescription(int defaultStep, int defaultStepBase, int stepScaleFactor, StepValueShouldBe stepValueShouldBe = StepValueShouldBeReal)
50            : defaultStep(defaultStep)
51            , defaultStepBase(defaultStepBase)
52            , stepScaleFactor(stepScaleFactor)
53            , stepValueShouldBe(stepValueShouldBe)
54        {
55        }
56
57        StepDescription()
58            : defaultStep(1)
59            , defaultStepBase(0)
60            , stepScaleFactor(1)
61            , stepValueShouldBe(StepValueShouldBeReal)
62        {
63        }
64
65        Decimal defaultValue() const
66        {
67            return defaultStep * stepScaleFactor;
68        }
69    };
70
71    StepRange();
72    StepRange(const StepRange&);
73    StepRange(const Decimal& stepBase, const Decimal& minimum, const Decimal& maximum, const Decimal& step, const StepDescription&);
74    Decimal alignValueForStep(const Decimal& currentValue, const Decimal& newValue) const;
75    Decimal clampValue(const Decimal& value) const;
76    bool hasStep() const { return m_hasStep; }
77    Decimal maximum() const { return m_maximum; }
78    Decimal minimum() const { return m_minimum; }
79    static Decimal parseStep(AnyStepHandling, const StepDescription&, const String&);
80    Decimal step() const { return m_step; }
81    Decimal stepBase() const { return m_stepBase; }
82    bool stepMismatch(const Decimal&) const;
83
84    // Clamp the middle value according to the step
85    Decimal defaultValue() const
86    {
87        return clampValue((m_minimum + m_maximum) / 2);
88    }
89
90    // Map value into 0-1 range
91    Decimal proportionFromValue(const Decimal& value) const
92    {
93        if (m_minimum == m_maximum)
94            return 0;
95
96        return (value - m_minimum) / (m_maximum - m_minimum);
97    }
98
99    // Map from 0-1 range to value
100    Decimal valueFromProportion(const Decimal& proportion) const
101    {
102        return m_minimum + proportion * (m_maximum - m_minimum);
103    }
104
105private:
106    StepRange& operator =(const StepRange&);
107    Decimal acceptableError() const;
108    Decimal roundByStep(const Decimal& value, const Decimal& base) const;
109
110    const Decimal m_maximum; // maximum must be >= minimum.
111    const Decimal m_minimum;
112    const Decimal m_step;
113    const Decimal m_stepBase;
114    const StepDescription m_stepDescription;
115    const bool m_hasStep;
116};
117
118}
119
120#endif // StepRange_h
121