/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.taobao.weex.ui.view;

import android.content.Context;
import android.graphics.Canvas;
import android.support.annotation.Nullable;
import android.text.Layout;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;

import com.taobao.weex.ui.component.WXText;
import com.taobao.weex.ui.view.gesture.WXGesture;
import com.taobao.weex.ui.view.gesture.WXGestureObservable;

import java.lang.ref.WeakReference;

/**
 * TextView wrapper
 */
public class WXTextView extends View implements WXGestureObservable, IWXTextView,
                                                IRenderStatus<WXText>, IRenderResult<WXText> {

  private WeakReference<WXText> mWeakReference;
  private WXGesture wxGesture;
  private Layout textLayout;
  private boolean mIsLabelSet = false;

  public WXTextView(Context context) {
    super(context);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.save();
    Layout layout= getTextLayout();
    if(layout!=null){
      canvas.translate(getPaddingLeft(),getPaddingTop());
      layout.draw(canvas);
    }
    canvas.restore();
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    boolean result = super.onTouchEvent(event);
    if (wxGesture != null) {
      result |= wxGesture.onTouch(this, event);
    }
    return result;
  }

  @Override
  public void registerGestureListener(WXGesture wxGesture) {
    this.wxGesture = wxGesture;
  }

  @Override
  public CharSequence getText() {
    return textLayout.getText();
  }

  public Layout getTextLayout() {
    return textLayout;
  }

  public void setTextLayout(Layout layout) {
    this.textLayout = layout;
    if(layout!=null && !mIsLabelSet){
      setContentDescription(layout.getText());
    }
    if (mWeakReference != null) {
      WXText wxText = mWeakReference.get();
      if (wxText != null) {
        wxText.readyToRender();
      }
    }
  }

  public void setAriaLabel(String label){
    if(!TextUtils.isEmpty(label)){
      mIsLabelSet = true;
      setContentDescription(label);
    }else{
      mIsLabelSet = false;
      if(textLayout != null){
        setContentDescription(textLayout.getText());
      }
    }

  }

  @Override
  public void holdComponent(WXText component) {
    mWeakReference = new WeakReference<>(component);
  }

  @Nullable
  @Override
  public WXText getComponent() {
     return null != mWeakReference ? mWeakReference.get() : null;
  }
}
