package com.florianmski.tracktoid.utils;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import com.florianmski.tracktoid.TraktoidPrefs;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.TimeZone;
public class Utils
{
// from http://stackoverflow.com/a/11946496
public static String sparseArrayToString(SparseArray<?> sparseArray)
{
StringBuilder result = new StringBuilder();
if (sparseArray == null)
return "null";
result.append('{');
for (int i = 0; i < sparseArray.size(); i++)
{
result.append(sparseArray.keyAt(i));
result.append(" => ");
if (sparseArray.valueAt(i) == null)
result.append("null");
else
result.append(sparseArray.valueAt(i).toString());
if (i < sparseArray.size() - 1)
result.append(", ");
}
result.append('}');
return result.toString();
}
public static long getPSTTimestamp()
{
TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles");
Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(timeZone);
return calendar.getTimeInMillis() / 1000;
}
public static String getSeasonEpisodeString(int season, int episode)
{
return String.format("S%02dE%02d", season, episode);
}
public static String readInputStream(InputStream in) throws IOException
{
StringBuffer stream = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = in.read(b)) != -1; )
stream.append(new String(b, 0, n));
return stream.toString();
}
// http://stackoverflow.com/questions/929103/convert-a-number-range-to-another-range-maintaining-ratio
public static float linearConversion(float oldValue, float oldMin, float oldMax, float newMin, float newMax)
{
// check that oldValue is between oldMin and oldMax
if (oldValue > oldMax)
oldValue = oldMax;
else if (oldValue < oldMin)
oldValue = oldMin;
float oldRange = (oldMax - oldMin);
float NewRange = (newMax - newMin);
return (((oldValue - oldMin) * NewRange) / oldRange) + newMin;
}
public static int booleanToInt(Boolean bool)
{
return (bool != null && bool) ? 1 : 0;
}
public static int getActionBarHeight(Context context)
{
final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(new int[]{android.support.v7.appcompat.R.attr.actionBarSize});
int height = styledAttributes.getDimensionPixelSize(0, 0);
styledAttributes.recycle();
return height;
}
// borrowed there https://github.com/astuetz/PagerSlidingTabStrip/blob/master/sample/src/com/astuetz/viewpager/extensions/sample/MainActivity.java
// change color background of a view with a nice transition
public static TransitionDrawable generateTransitionDrawable(Drawable oldBackground, int newColor)
{
// nothing to do
if (oldBackground != null && oldBackground instanceof ColorDrawable && ((ColorDrawable) oldBackground).getColor() == newColor)
return null;
Drawable colorDrawable = new ColorDrawable(newColor);
if (oldBackground == null)
oldBackground = new ColorDrawable(Color.TRANSPARENT);
return new TransitionDrawable(new Drawable[]{oldBackground, colorDrawable});
}
public static void changeColor(Drawable oldBackground, int newColor, final View v)
{
final Handler handler = new Handler();
Drawable.Callback drawableCallback = new Drawable.Callback()
{
@Override
public void invalidateDrawable(Drawable who)
{
v.setBackgroundDrawable(who);
}
@Override
public void scheduleDrawable(Drawable who, Runnable what, long when)
{
handler.postAtTime(what, when);
}
@Override
public void unscheduleDrawable(Drawable who, Runnable what)
{
handler.removeCallbacks(what);
}
};
TransitionDrawable td = generateTransitionDrawable(oldBackground, newColor);
if (td == null)
return;
// workaround for broken ActionBarContainer drawable handling on
// pre-API 17 builds
// https://github.com/android/platform_frameworks_base/commit/a7cc06d82e45918c37429a59b14545c6a57db4e4
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
td.setCallback(drawableCallback);
else
v.setBackgroundDrawable(td);
td.startTransition(300);
}
public static int getColorFromAttribute(Context context, int attr)
{
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(attr, typedValue, true);
return typedValue.data;
}
private static float interpolate(float a, float b, float proportion)
{
return (a + ((b - a) * proportion));
}
// from http://stackoverflow.com/a/7871291 and found this idea in the EyeEm app
public static int interpolateColor(int a, int b, float proportion)
{
float[] hsva = new float[3];
float[] hsvb = new float[3];
Color.colorToHSV(a, hsva);
Color.colorToHSV(b, hsvb);
for (int i = 0; i < 3; i++)
hsvb[i] = interpolate(hsva[i], hsvb[i], proportion);
return Color.HSVToColor(hsvb);
}
public static void writeToSD(String path, String filename) throws IOException
{
File sd = Environment.getExternalStorageDirectory();
if (sd.canWrite())
{
File currentFile = new File(path, filename);
File backupFile = new File(sd, filename);
if (currentFile.exists())
{
FileChannel src = new FileInputStream(currentFile).getChannel();
FileChannel dst = new FileOutputStream(backupFile).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
}
public static void writeDBToSD(Context context, String dbName) throws IOException
{
writeToSD(context.getFilesDir().getPath().replace("files", "databases"), dbName);
}
public static String pluralize(int count, String singular)
{
return pluralize(count, singular, singular.concat("s"));
}
public static String pluralize(int count, String singular, String plural)
{
return (count == 1 ? singular : plural);
}
public static String join(Collection<String> s, String delimiter)
{
if (s == null || s.isEmpty())
return null;
Iterator<String> iterator = s.iterator();
StringBuilder builder = new StringBuilder(iterator.next());
while (iterator.hasNext())
builder.append(delimiter).append(iterator.next());
return builder.toString();
}
public static void eraseAppData(Context context)
{
// erase prefs
TraktoidPrefs.INSTANCE.clear();
// erase folders
deleteDir(context.getCacheDir());
deleteDir(context.getFilesDir());
// erase databases
for(String name : context.databaseList())
context.deleteDatabase(name);
}
private static boolean deleteDir(File dir)
{
if(dir == null)
return false;
if (dir.isDirectory())
{
String[] children = dir.list();
for (String child : children)
{
if (!deleteDir(new File(dir, child)))
return false;
}
}
return dir.delete();
}
public static void disableClipOnParents(View v)
{
if (v.getParent() == null)
return;
if (v instanceof ViewGroup)
((ViewGroup) v).setClipChildren(false);
if (v.getParent() instanceof View)
disableClipOnParents((View) v.getParent());
}
}