1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This file contains implementation details, the public interface is declared
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// in time_format.h.
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef UI_BASE_L10N_FORMATTER_H_
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define UI_BASE_L10N_FORMATTER_H_
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/basictypes.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/lazy_instance.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/icu/source/common/unicode/unistr.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/icu/source/i18n/unicode/plurfmt.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/icu/source/i18n/unicode/plurrule.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/base/l10n/time_format.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/base/ui_base_export.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ui {
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct Pluralities;
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Formatter for a (format, length) combination.  May either be instantiated
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// with four parameters for use in TimeFormat::Simple() or with ten parameters
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// for use in TimeFormat::Detailed().
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class Formatter {
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  enum Unit {
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UNIT_SEC,
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UNIT_MIN,
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UNIT_HOUR,
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UNIT_DAY,
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UNIT_COUNT  // Enum size counter, not a unit.  Must be last.
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  enum TwoUnits {
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TWO_UNITS_MIN_SEC,
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TWO_UNITS_HOUR_MIN,
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TWO_UNITS_DAY_HOUR,
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TWO_UNITS_COUNT      // Enum size counter, not a unit pair.  Must be last.
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Formatter(const Pluralities& sec_pluralities,
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& min_pluralities,
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& hour_pluralities,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& day_pluralities);
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Formatter(const Pluralities& sec_pluralities,
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& min_pluralities,
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& hour_pluralities,
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& day_pluralities,
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& min_sec_pluralities1,
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& min_sec_pluralities2,
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& hour_min_pluralities1,
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& hour_min_pluralities2,
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& day_hour_pluralities1,
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            const Pluralities& day_hour_pluralities2);
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Format(Unit unit, int value, icu::UnicodeString& formatted_string) const;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Format(TwoUnits units,
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              int value_1,
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              int value_2,
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              icu::UnicodeString& formatted_string) const;
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Create a hard-coded fallback plural format.  This will never be called
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // unless translators make a mistake.
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<icu::PluralFormat> CreateFallbackFormat(
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const icu::PluralRules& rules,
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const Pluralities& pluralities) const;
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<icu::PluralFormat> InitFormat(const Pluralities& pluralities);
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<icu::PluralFormat> simple_format_[UNIT_COUNT];
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<icu::PluralFormat> detailed_format_[TWO_UNITS_COUNT][2];
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(Formatter);
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Class to hold all Formatters, intended to be used in a global LazyInstance.
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class UI_BASE_EXPORT FormatterContainer {
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FormatterContainer();
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ~FormatterContainer();
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const Formatter* Get(TimeFormat::Format format,
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       TimeFormat::Length length) const;
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void ResetForTesting() {
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Shutdown();
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Initialize();
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Initialize();
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Shutdown();
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<Formatter>
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      formatter_[TimeFormat::FORMAT_COUNT][TimeFormat::LENGTH_COUNT];
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FormatterContainer);
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Windows compilation requires full definition of FormatterContainer before
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// LazyInstance<FormatterContainter> may be declared.
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)extern UI_BASE_EXPORT base::LazyInstance<FormatterContainer> g_container;
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// For use in unit tests only.
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)extern UI_BASE_EXPORT bool formatter_force_fallback;
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace ui
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
115