// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.infobar; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * A class that keeps the state of the different translation options and * languages. */ public class TranslateOptions { // This would be an enum but they are not good for mobile. // The checkBoundaries method below needs to be updated if new options are added. private static final int NEVER_LANGUAGE = 0; private static final int NEVER_DOMAIN = 1; private static final int ALWAYS_LANGUAGE = 2; private final String[] mAllLanguages; // Will reflect the state before the object was ever modified private final boolean[] mOriginalOptions; private final int mOriginalSourceLanguageIndex; private final int mOriginalTargetLanguageIndex; private boolean[] mOptions; private int mSourceLanguageIndex; private int mTargetLanguageIndex; private TranslateOptions(int sourceLanguageCode, int targetLanguageCode, String[] allLanguages, boolean neverLanguage, boolean neverDomain, boolean alwaysLanguage, boolean[] originalOptions) { mAllLanguages = allLanguages; mSourceLanguageIndex = sourceLanguageCode; mTargetLanguageIndex = targetLanguageCode; mOptions = new boolean[3]; mOptions[NEVER_LANGUAGE] = neverLanguage; mOptions[NEVER_DOMAIN] = neverDomain; mOptions[ALWAYS_LANGUAGE] = alwaysLanguage; if (originalOptions == null) { mOriginalOptions = mOptions.clone(); } else { mOriginalOptions = originalOptions.clone(); } mOriginalSourceLanguageIndex = mSourceLanguageIndex; mOriginalTargetLanguageIndex = mTargetLanguageIndex; } public TranslateOptions(int sourceLanguageCode, int targetLanguageCode, String[] allLanguages, boolean alwaysTranslate) { this(sourceLanguageCode, targetLanguageCode, allLanguages, false, false, alwaysTranslate, null); } /** * Copy constructor */ public TranslateOptions(TranslateOptions other) { this(other.mSourceLanguageIndex, other.mTargetLanguageIndex, other.mAllLanguages, other.mOptions[NEVER_LANGUAGE], other.mOptions[NEVER_DOMAIN], other.mOptions[ALWAYS_LANGUAGE], other.mOriginalOptions); } public String sourceLanguage() { if (checkLanguageBoundaries(mSourceLanguageIndex)) return mAllLanguages[mSourceLanguageIndex]; return ""; } public String targetLanguage() { if (checkLanguageBoundaries(mTargetLanguageIndex)) return mAllLanguages[mTargetLanguageIndex]; return ""; } public int sourceLanguageIndex() { return checkLanguageBoundaries(mSourceLanguageIndex) ? mSourceLanguageIndex : 0; } public int targetLanguageIndex() { return checkLanguageBoundaries(mTargetLanguageIndex) ? mTargetLanguageIndex : 0; } public boolean optionsChanged() { return (mSourceLanguageIndex != mOriginalSourceLanguageIndex) || (mTargetLanguageIndex != mOriginalTargetLanguageIndex) || (mOptions[NEVER_LANGUAGE] != mOriginalOptions[NEVER_LANGUAGE]) || (mOptions[NEVER_DOMAIN] != mOriginalOptions[NEVER_DOMAIN]) || (mOptions[ALWAYS_LANGUAGE] != mOriginalOptions[ALWAYS_LANGUAGE]); } public List<String> allLanguages() { return Collections.unmodifiableList(Arrays.asList(mAllLanguages)); } public boolean neverTranslateLanguageState() { return mOptions[NEVER_LANGUAGE]; } public boolean alwaysTranslateLanguageState() { return mOptions[ALWAYS_LANGUAGE]; } public boolean neverTranslateDomainState() { return mOptions[NEVER_DOMAIN]; } public boolean setSourceLanguage(int languageIndex) { boolean canSet = canSetLanguage(languageIndex, mTargetLanguageIndex); if (canSet) { mSourceLanguageIndex = languageIndex; } return canSet; } public boolean setTargetLanguage(int languageIndex) { boolean canSet = canSetLanguage(mSourceLanguageIndex, languageIndex); if (canSet) { mTargetLanguageIndex = languageIndex; } return canSet; } /** * Sets the new state of never translate domain. * * @return true if the toggling was possible */ public boolean toggleNeverTranslateDomainState(boolean value) { return toggleState(NEVER_DOMAIN, value); } /** * Sets the new state of never translate language. * * @return true if the toggling was possible */ public boolean toggleNeverTranslateLanguageState(boolean value) { // Do not toggle if we are activating NeverLanguge but AlwaysTranslate // for a language pair with the same source language is already active. if (mOptions[ALWAYS_LANGUAGE] && value) { return false; } return toggleState(NEVER_LANGUAGE, value); } /** * Sets the new state of never translate a language pair. * * @return true if the toggling was possible */ public boolean toggleAlwaysTranslateLanguageState(boolean value) { // Do not toggle if we are activating AlwaysLanguge but NeverLanguage is active already. if (mOptions[NEVER_LANGUAGE] && value) { return false; } return toggleState(ALWAYS_LANGUAGE, value); } private boolean toggleState(int element, boolean newValue) { if (!checkElementBoundaries(element)) return false; mOptions[element] = newValue; return true; } private boolean checkLanguageBoundaries(int index) { return index >= 0 && index < mAllLanguages.length; } private boolean canSetLanguage(int sourceIndex, int targetIndex) { if (sourceIndex == targetIndex) return false; return checkLanguageBoundaries(sourceIndex) && checkLanguageBoundaries(targetIndex); } private static boolean checkElementBoundaries(int element) { return element >= NEVER_LANGUAGE && element <= ALWAYS_LANGUAGE; } @Override public String toString() { return new StringBuilder() .append(sourceLanguage()) .append(" -> ") .append(targetLanguage()) .append(" - ") .append("Never Language:") .append(mOptions[NEVER_LANGUAGE]) .append(" Always Language:") .append(mOptions[ALWAYS_LANGUAGE]) .append(" Never Domain:") .append(mOptions[NEVER_DOMAIN]) .toString(); } }