package com.algobase.widgets;

import android.os.CountDownTimer;
import android.os.Handler;
import android.content.Context;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.util.AttributeSet;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.Rect;
import android.graphics.Point;
import android.graphics.Path;

import com.algobase.share.system.*;

public class DataView extends View {

  int width;
  int height;
  double offset;

  String label;
  String value;
  String unit;

  int intValue = 0;
  int curValue = 0;

  Context context;
  Handler handler = new Handler();

  Typeface tface = Typeface.MONOSPACE;

  int disp_width = 0;

  int label_clr = Color.rgb(200,200,200);
  int value_clr = Color.WHITE;;
  int unit_clr = Color.WHITE;

  float text_size_f = 1.0f;
  float val_size_f = 1.0f;

  boolean center = false;
  boolean marker = false;

  Paint paint = new Paint();
  Rect bounds = new Rect();

  int DipToPixels(float dp)
  { float dpi = context.getResources().getDisplayMetrics().densityDpi;
    return (int)(0.5 + dp * (dpi/160f));
  }


  public DataView(Context c) { super(c); init(c); }
  public DataView(Context c, AttributeSet a) { super(c,a); init(c); }
  public DataView(Context c, AttributeSet a, int i) { super(c,a,i); init(c); }

  void init(Context c) {
    context = c;
/*
    tface =  Typeface.createFromAsset(context.getAssets(),
                                          "fonts/Roboto-Regular.ttf");
*/
  }


  void drawHline(Canvas canvas, float x, int clr)
  { paint.setColor(clr);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(4);
    paint.setAntiAlias(true);
    canvas.drawLine(x, 0.35f*height, x, 0.85f*height, paint);
   }

  void drawArrow(Canvas canvas, float x, int clr)
  { paint.setColor(clr);
    paint.setStyle(Paint.Style.FILL);
    paint.setAntiAlias(true);

    //float len = 0.45f*height;
    //float len = 0.55f*height;

    float len = 0.5f*height;

    float d = 0.03f*len;
    float r = 5*d;

    Path path = new Path();
    path.moveTo(-d,0);
    path.lineTo(-d,-len);
    path.lineTo(-r,-len);
    path.lineTo( 0,-(len+1.8f*r));
    path.lineTo(+r,-len);
    path.lineTo(+d,-len);
    path.lineTo(+d,0);
    path.close();

    canvas.save();
    canvas.translate(x,0.85f*height);
    canvas.drawPath(path,paint);
    canvas.restore();
   }



  @Override
  protected void onSizeChanged(int w, int h, int old_w, int old_h)
  { width = w;
    height = h;
    super.onSizeChanged(w,h,old_w,old_h);
  }


  @Override
  protected void onDraw(Canvas canvas) 
  {
    float yoff = 0;

  //float dp = height/90;

    float dp = DipToPixels(1);

    if (width < disp_width) { // small field
      dp = 0.9f * dp;
    }

    dp *= text_size_f;

    if (dp > height/90.0f) dp = height/90.0f;


    int ts_value = (int)(46*dp*val_size_f);
    int ts_label = (int)(18*dp);
    int ts_unit  = (int)(20*dp);


    if (marker) drawArrow(canvas,width/2,label_clr);

    paint.setStyle(Paint.Style.FILL);
    paint.setAntiAlias(true);

    if (label != null)
    { 
      paint.setTextSize(ts_label);
      paint.setColor(label_clr);
      paint.setTypeface(Typeface.DEFAULT);
      paint.setTextAlign(Align.LEFT);

      String txt = label.replaceAll(".","H");
      paint.getTextBounds(txt,0,label.length(),bounds);
      int tw = bounds.width();
      int th = bounds.height();

      float d = 0.06f*height;
      if (d > 20) d = 20;

      canvas.drawText(label,d,th+1.25f*d,paint);
     }


    if (value != null)
    { float x = 0.67f*width;

      paint.setTextSize(ts_value);
      paint.setColor(value_clr);

      paint.setTypeface(tface);

      String txt = value.replaceAll(".","0");
      paint.getTextBounds(txt,0,value.length(),bounds);
      int tw = bounds.width();
      int th = bounds.height();

      if (value.indexOf(";") != -1) 
      { tw /= 2;
        th *= 2;
       }

      if (val_size_f >= 1.0f && tw > 0.9f*width) 
      { ts_value = (int)((0.9*ts_value*width)/tw);
        if (ts_value < (int)(18*dp)) ts_value = (int)(18*dp);
        paint.setTextSize(ts_value);
        paint.getTextBounds(txt,0,value.length(),bounds);
        tw = bounds.width();
        th = bounds.height();
       }


      float cw = ((float)tw)/value.length();

      float y = (height + th)/2;

      if (width > 3*height)   // wide
         yoff = 0.03f * height;
      else
         yoff = 0.09f * height;
       
      y += yoff;

      if (!center)
        paint.setTextAlign(Align.RIGHT);
      else
        { x = width/2;
          paint.setTextAlign(Align.CENTER);
         }

      x -= offset*cw;


      if (value.indexOf(".") != -1 && value.length() < 8)
      { // floating point number

        paint.setTextAlign(Align.LEFT);

        int p = value.indexOf(".");
        String s1a = value.substring(0,p);
        String s1b = value.substring(p+1);

        paint.getTextBounds(s1a,0,s1a.length(),bounds);
        float len1 = bounds.width();

        paint.getTextBounds(s1b,0,s1b.length(),bounds);
        float len2 = bounds.height();

        float len = len1 + len2 + 0.7f*cw;

        if (center)
          x -= len/2;
        else
          x -= (len - 0.3f*cw);

        float x1 = x;
        float x2 = x + len1 + 0.7f*cw;

        canvas.drawText(s1a,x1,y,paint);
        canvas.drawText(s1b,x2,y,paint);

        paint.setTextSize((int)(0.64f*ts_value));
        canvas.drawText(".",x2-0.57f*cw,y,paint);
        paint.setTextSize(ts_value);
       }
      else
      if (value.indexOf(":") != -1)
        { // time string (hh:mm:ss or mm:ss)

          if (value.length() == 5)
          { // mm:ss
            String s1a =  value.substring(0,2) + "   ";
            String s1b = "   " + value.substring(3,5);

            if (tface != Typeface.MONOSPACE)
            { s1a = s1a + "    ";
              s1b = "    " + s1b;
            }
            canvas.drawText(s1a,x+0.25f*cw,y,paint);
            canvas.drawText(s1b,x-0.25f*cw,y,paint);
            paint.setTextSize((int)(0.65f*ts_value));
            canvas.drawText(":",x,y-0.22f*th,paint);
           }
          else
          { // hh:mm:ss or hhh:mm:ss
            String s1a = "";
            String s1b = "";
            if (value.length() == 8)
            { s1a = value.substring(0,2); 
              if (tface == Typeface.MONOSPACE)
                s1a += "   "; 
              else
                s1a += "       "; 
              s1a += value.substring(6,8);
              s1b = value.substring(3,5);
            }

            if (value.length() == 9) 
            { s1a = value.substring(0,3); 
              if (tface == Typeface.MONOSPACE)
                s1a += "   "; 
              else
                s1a += "       "; 
              s1a += value.substring(7,9) + " ";
              s1b = value.substring(4,6);
            }
  
            canvas.drawText(s1a,x,y,paint);
            canvas.drawText(s1b,x,y,paint);
            paint.setTextSize((int)(0.63f*ts_value));
            if (tface == Typeface.MONOSPACE)
              canvas.drawText(":   :",x,y-0.22f*th,paint);
            else
              canvas.drawText(":        :",x,y-0.22f*th,paint);
         
          }

          paint.setTextSize(ts_value);
        }
      else
        if (value.indexOf(";") != -1)
          { // two lines
            int p = value.indexOf(";");
            String s1 = value.substring(0,p);
            String s2 = value.substring(p+1);
            canvas.drawText(s1,x,y-0.8f*th,paint);
            canvas.drawText(s2,x,y+0.7f*th,paint);
           }
        else
          canvas.drawText(value,x,y,paint);

     }


    if (unit != null)
    { String s = unit;

      boolean move_down = false;

      if (s.startsWith("+")) move_down =true;


      paint.setColor(unit_clr);
      paint.setTextAlign(Align.LEFT);
      paint.setTypeface(Typeface.DEFAULT);
      paint.setTextSize(ts_unit);

      int sln = s.length();

      paint.getTextBounds(s,0,sln,bounds);

      float x = 0.73f*width;
      float y = (height + bounds.height())/2;

      y += 1.15f*yoff;

      if (move_down)
      { //paint.setColor(value_clr);
        //x = width - bounds.width() - 5*dp;
        x = width - 11.5f*sln*dp;
        y = 0.94f*height;
       }
      canvas.drawText(s,x,y,paint);
     }

    super.onDraw(canvas);
  }



  @Override
  protected void onMeasure(int widthSpec, int heightSpec)
  { int measuredWidth = MeasureSpec.getSize(widthSpec);
    int measuredHeight = MeasureSpec.getSize(heightSpec);
    setMeasuredDimension( measuredWidth, measuredHeight);
   }


  public void setLabel(String l) { 
      label = l;
      setContentDescription(label);
  }

  public void setUnit(String u) { unit = u; }
  public void setValue(String val) { value = val; }

  public void setIntValue(int x) { 

      if (intValue == x) {
          setValue("" + curValue); 
          invalidate(); 
          return;
      }

      boolean thread_running = (intValue != curValue);

      intValue = x;

      if (thread_running) return;

      new MyThread() {
        public void run() {
          while (curValue != intValue)
          { int diff = intValue - curValue;
           /*
            int step = 1;
            int delay = 1000/Math.abs(diff);
           */

            //int step = 1 + Math.abs(diff)/4;
            int step = 1 + Math.abs(diff)/5;

            int delay = 500;

            curValue += (diff > 0) ? +step : -step;
            handler.post(new Runnable() {
                   public void run() { setValue("" + curValue); invalidate(); }
            });
            sleep(delay);
          }
        }
      }.start();

  }


  public void setDisplayWidth(int w) { disp_width = w; }

  public void setLabelColor(int clr) { label_clr = clr; }
  public void setUnitColor(int clr)  { unit_clr = clr; }
  public void setValueColor(int clr) { value_clr = clr; }

  public void setFont(Typeface tf) { tface = tf; }

  public void setTextSizeFactor(float f) { text_size_f = f; }
  public void setValueSizeFactor(float f) { val_size_f = f; }

  public void setMarker(boolean b) { marker = b; }
  public void setCenter(boolean b) { center = b; }
  public void setOffset(double off) { offset = off; }
}

