1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_OFFSET_H
17#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_OFFSET_H
18
19#include <cmath>
20#include <limits>
21
22#include "base/geometry/size.h"
23#include "base/utils/utils.h"
24#include "core/components/common/properties/animation_option.h"
25
26namespace OHOS::Ace {
27class Offset {
28public:
29    Offset() = default;
30    ~Offset() = default;
31    Offset(double deltaX, double deltaY) : deltaX_(deltaX), deltaY_(deltaY) {}
32
33    void Reset()
34    {
35        deltaX_ = 0.0;
36        deltaY_ = 0.0;
37        deltaXAnimationOption_ = AnimationOption();
38        deltaYAnimationOption_ = AnimationOption();
39    }
40
41    static Offset Zero()
42    {
43        return Offset();
44    }
45
46    static Offset ErrorOffset()
47    {
48        return Offset((std::numeric_limits<double>::max)(), (std::numeric_limits<double>::max)());
49    }
50
51    bool IsZero() const
52    {
53        return operator==(Offset());
54    }
55
56    bool IsErrorOffset() const
57    {
58        return operator==(ErrorOffset());
59    }
60
61    double GetX() const
62    {
63        return deltaX_;
64    }
65
66    double GetY() const
67    {
68        return deltaY_;
69    }
70
71    void SetX(double x, const AnimationOption& option = AnimationOption())
72    {
73        deltaX_ = x;
74        deltaXAnimationOption_ = option;
75    }
76
77    void SetY(double y, const AnimationOption& option = AnimationOption())
78    {
79        deltaY_ = y;
80        deltaYAnimationOption_ = option;
81    }
82
83    AnimationOption GetXAnimationOption() const
84    {
85        return deltaXAnimationOption_;
86    }
87
88    AnimationOption GetYAnimationOption() const
89    {
90        return deltaYAnimationOption_;
91    }
92
93    double GetDistance() const
94    {
95        return std::sqrt((deltaX_ * deltaX_) + (deltaY_ * deltaY_));
96    }
97
98    Offset operator+(const Offset& offset) const
99    {
100        return Offset(deltaX_ + offset.deltaX_, deltaY_ + offset.deltaY_);
101    }
102
103    Offset operator+(const Size& size) const
104    {
105        return Offset(deltaX_ + size.Width(), deltaY_ + size.Height());
106    }
107
108    Offset operator-(const Offset& offset) const
109    {
110        return Offset(deltaX_ - offset.deltaX_, deltaY_ - offset.deltaY_);
111    }
112
113    Offset operator-(const Size& size) const
114    {
115        return Offset(deltaX_ - size.Width(), deltaY_ - size.Height());
116    }
117
118    Offset operator*(double value) const
119    {
120        return Offset(deltaX_ * value, deltaY_ * value);
121    }
122
123    Offset operator/(double value) const
124    {
125        if (NearZero(value)) {
126            return ErrorOffset();
127        }
128        return Offset(deltaX_ / value, deltaY_ / value);
129    }
130
131    Offset& operator+=(const Offset& offset)
132    {
133        deltaX_ += offset.deltaX_;
134        deltaY_ += offset.deltaY_;
135        return *this;
136    }
137
138    Offset& operator-=(const Offset& offset)
139    {
140        deltaX_ -= offset.deltaX_;
141        deltaY_ -= offset.deltaY_;
142        return *this;
143    }
144
145    bool operator==(const Offset& offset) const
146    {
147        return NearEqual(deltaX_, offset.deltaX_) && NearEqual(deltaY_, offset.deltaY_);
148    }
149
150    bool operator!=(const Offset& offset) const
151    {
152        return !operator==(offset);
153    }
154
155    std::string ToString() const
156    {
157        std::stringstream ss;
158        ss << "Offset (" << std::fixed << std::setprecision(2) << deltaX_ << ", " << deltaY_ << ")";
159        std::string output = ss.str();
160        return output;
161    }
162
163    bool IsPositiveOffset() const
164    {
165        return deltaX_ >= 0 && deltaY_ >= 0;
166    }
167
168private:
169    double deltaX_ = 0.0;
170    double deltaY_ = 0.0;
171    AnimationOption deltaXAnimationOption_;
172    AnimationOption deltaYAnimationOption_;
173};
174} // namespace OHOS::Ace
175
176#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_OFFSET_H
177