/*
 * Copyright 2010 Google Inc.
 *
 * Licensed 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.google.gwt.sample.showcase.client.content.cell;

import com.google.gwt.cell.client.AbstractEditableCell;
import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.cell.client.DatePickerCell;
import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.IconCellDecorator;
import com.google.gwt.cell.client.ImageCell;
import com.google.gwt.cell.client.NumberCell;
import com.google.gwt.cell.client.SelectionCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.cell.client.TextInputCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.sample.showcase.client.ContentWidget;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseData;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseRaw;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseSource;
import com.google.gwt.sample.showcase.client.content.cell.ContactDatabase.Category;
import com.google.gwt.sample.showcase.client.content.cell.ContactDatabase.ContactInfo;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Example file.
 */
@ShowcaseRaw({"ContactDatabase.java", "CwCellSampler.ui.xml"})
public class CwCellSampler extends ContentWidget {

  /**
   * The UiBinder interface used by this example.
   */
  @ShowcaseSource
  interface Binder extends UiBinder<Widget, CwCellSampler> {
  }

  /**
   * The constants used in this Content Widget.
   */
  @ShowcaseSource
  public static interface CwConstants extends Constants {
    String cwCellSamplerDescription();

    String cwCellSamplerName();
  }

  /**
   * The images used for this example.
   */
  @ShowcaseSource
  static interface Images extends ClientBundle {
    ImageResource contactsGroup();
  }

  /**
   * Get a cell value from a record.
   *
   * @param <C> the cell type
   */
  @ShowcaseSource
  private static interface GetValue<C> {
    C getValue(ContactInfo contact);
  }

  /**
   * A pending change to a {@link ContactInfo}. Changes aren't committed
   * immediately to illustrate that cells can remember their pending changes.
   *
   * @param <T> the data type being changed
   */
  @ShowcaseSource
  private abstract static class PendingChange<T> {
    private final ContactInfo contact;
    private final T value;

    public PendingChange(ContactInfo contact, T value) {
      this.contact = contact;
      this.value = value;
    }

    /**
     * Commit the change to the contact.
     */
    public void commit() {
      doCommit(contact, value);
    }

    /**
     * Update the appropriate field in the {@link ContactInfo}.
     *
     * @param contact the contact to update
     * @param value the new value
     */
    protected abstract void doCommit(ContactInfo contact, T value);
  }

  /**
   * Updates the birthday.
   */
  @ShowcaseSource
  private static class BirthdayChange extends PendingChange<Date> {

    public BirthdayChange(ContactInfo contact, Date value) {
      super(contact, value);
    }

    @Override
    protected void doCommit(ContactInfo contact, Date value) {
      contact.setBirthday(value);
    }
  }

  /**
   * Updates the category.
   */
  @ShowcaseSource
  private static class CategoryChange extends PendingChange<Category> {

    public CategoryChange(ContactInfo contact, Category value) {
      super(contact, value);
    }

    @Override
    protected void doCommit(ContactInfo contact, Category value) {
      contact.setCategory(value);
    }
  }

  /**
   * Updates the first name.
   */
  @ShowcaseSource
  private static class FirstNameChange extends PendingChange<String> {

    public FirstNameChange(ContactInfo contact, String value) {
      super(contact, value);
    }

    @Override
    protected void doCommit(ContactInfo contact, String value) {
      contact.setFirstName(value);
    }
  }

  /**
   * Updates the last name.
   */
  @ShowcaseSource
  private static class LastNameChange extends PendingChange<String> {

    public LastNameChange(ContactInfo contact, String value) {
      super(contact, value);
    }

    @Override
    protected void doCommit(ContactInfo contact, String value) {
      contact.setLastName(value);
    }
  }

  /**
   * The main CellTable.
   */
  @ShowcaseData
  @UiField(provided = true)
  CellTable<ContactInfo> cellTable;

  /**
   * The commit button.
   */
  @ShowcaseData
  @UiField
  Button commitButton;

  /**
   * The redraw button.
   */
  @ShowcaseData
  @UiField
  Button redrawButton;

  /**
   * The list of cells that are editable.
   */
  @ShowcaseData
  private List<AbstractEditableCell<?, ?>> editableCells;

  /**
   * The list of pending changes.
   */
  @ShowcaseData
  private List<PendingChange<?>> pendingChanges = new ArrayList<
      PendingChange<?>>();

  /**
   * Constructor.
   *
   * @param constants the constants
   */
  public CwCellSampler(CwConstants constants) {
    super(constants.cwCellSamplerName(), constants.cwCellSamplerDescription(),
        false, "ContactDatabase.java", "CwCellSampler.ui.xml");
  }

  /**
   * Initialize this example.
   */
  @ShowcaseSource
  @Override
  public Widget onInitialize() {
    Images images = GWT.create(Images.class);

    // Create the table.
    editableCells = new ArrayList<AbstractEditableCell<?, ?>>();
    cellTable = new CellTable<ContactInfo>(6, ContactInfo.KEY_PROVIDER);
    ContactDatabase.get().addDataDisplay(cellTable);

    // CheckboxCell.
    final Category[] categories = ContactDatabase.get().queryCategories();
    addColumn(new CheckboxCell(), "Checkbox", new GetValue<Boolean>() {
      public Boolean getValue(ContactInfo contact) {
        // Checkbox indicates that the contact is a relative.
        // Index 0 = Family.
        return contact.getCategory() == categories[0];
      }
    }, new FieldUpdater<ContactInfo, Boolean>() {
      public void update(int index, ContactInfo object, Boolean value) {
        if (value) {
          // If a relative, use the Family Category.
          pendingChanges.add(new CategoryChange(object, categories[0]));
        } else {
          // If not a relative, use the Contacts Category.
          pendingChanges.add(
              new CategoryChange(object, categories[categories.length - 1]));
        }
      }
    });

    // TextCell.
    addColumn(new TextCell(), "Text", new GetValue<String>() {
      public String getValue(ContactInfo contact) {
        return contact.getFullName();
      }
    }, null);

    // EditTextCell.
    addColumn(new EditTextCell(), "EditText", new GetValue<String>() {
      public String getValue(ContactInfo contact) {
        return contact.getFirstName();
      }
    }, new FieldUpdater<ContactInfo, String>() {
      public void update(int index, ContactInfo object, String value) {
        pendingChanges.add(new FirstNameChange(object, value));
      }
    });

    // TextInputCell.
    addColumn(new TextInputCell(), "TextInput", new GetValue<String>() {
      public String getValue(ContactInfo contact) {
        return contact.getLastName();
      }
    }, new FieldUpdater<ContactInfo, String>() {
      public void update(int index, ContactInfo object, String value) {
        pendingChanges.add(new LastNameChange(object, value));
      }
    });

    // ClickableTextCell.
    addColumn(new ClickableTextCell(), "ClickableText", new GetValue<String>() {
      public String getValue(ContactInfo contact) {
        return "Click " + contact.getFirstName();
      }
    }, new FieldUpdater<ContactInfo, String>() {
      public void update(int index, ContactInfo object, String value) {
        Window.alert("You clicked " + object.getFullName());
      }
    });

    // ActionCell.
    addColumn(new ActionCell<ContactInfo>(
        "Click Me", new ActionCell.Delegate<ContactInfo>() {
          public void execute(ContactInfo contact) {
            Window.alert("You clicked " + contact.getFullName());
          }
        }), "Action", new GetValue<ContactInfo>() {
      public ContactInfo getValue(ContactInfo contact) {
        return contact;
      }
    }, null);

    // ButtonCell.
    addColumn(new ButtonCell(), "Button", new GetValue<String>() {
      public String getValue(ContactInfo contact) {
        return "Click " + contact.getFirstName();
      }
    }, new FieldUpdater<ContactInfo, String>() {
      public void update(int index, ContactInfo object, String value) {
        Window.alert("You clicked " + object.getFullName());
      }
    });

    // DateCell.
    DateTimeFormat dateFormat = DateTimeFormat.getFormat(
        PredefinedFormat.DATE_MEDIUM);
    addColumn(new DateCell(dateFormat), "Date", new GetValue<Date>() {
      public Date getValue(ContactInfo contact) {
        return contact.getBirthday();
      }
    }, null);

    // DatePickerCell.
    addColumn(
        new DatePickerCell(dateFormat), "DatePicker", new GetValue<Date>() {
          public Date getValue(ContactInfo contact) {
            return contact.getBirthday();
          }
        }, new FieldUpdater<ContactInfo, Date>() {
          public void update(int index, ContactInfo object, Date value) {
            pendingChanges.add(new BirthdayChange(object, value));
          }
        });

    // NumberCell.
    addColumn(new NumberCell(), "Number", new GetValue<Number>() {
      @SuppressWarnings("deprecation")
      public Number getValue(ContactInfo contact) {
        Date today = new Date();
        Date birthday = contact.getBirthday();
        int age = today.getYear() - birthday.getYear();
        if (today.getMonth() > birthday.getMonth()
            || (today.getMonth() == birthday.getMonth()
                && today.getDate() > birthday.getDate())) {
          age--;
        }
        return age;
      }
    }, null);

    // IconCellDecorator.
    addColumn(
        new IconCellDecorator<String>(images.contactsGroup(), new TextCell()),
        "Icon", new GetValue<String>() {
          public String getValue(ContactInfo contact) {
            return contact.getCategory().getDisplayName();
          }
        }, null);

    // ImageCell.
    addColumn(new ImageCell(), "Image", new GetValue<String>() {
      public String getValue(ContactInfo contact) {
        return "contact.jpg";
      }
    }, null);

    // SelectionCell.
    List<String> options = new ArrayList<String>();
    for (Category category : categories) {
      options.add(category.getDisplayName());
    }
    addColumn(new SelectionCell(options), "Selection", new GetValue<String>() {
      public String getValue(ContactInfo contact) {
        return contact.getCategory().getDisplayName();
      }
    }, new FieldUpdater<ContactInfo, String>() {
      public void update(int index, ContactInfo object, String value) {
        for (Category category : categories) {
          if (category.getDisplayName().equals(value)) {
            pendingChanges.add(new CategoryChange(object, category));
            break;
          }
        }
      }
    });

    // Create the UiBinder.
    Binder uiBinder = GWT.create(Binder.class);
    Widget widget = uiBinder.createAndBindUi(this);

    // Add handlers to redraw or refresh the table.
    redrawButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        cellTable.redraw();
      }
    });
    commitButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        // Commit the changes.
        for (PendingChange<?> pendingChange : pendingChanges) {
          pendingChange.commit();
        }
        pendingChanges.clear();

        // Push the changes to the views.
        ContactDatabase.get().refreshDisplays();
      }
    });

    return widget;
  }

  @Override
  protected void asyncOnInitialize(final AsyncCallback<Widget> callback) {
    GWT.runAsync(CwCellSampler.class, new RunAsyncCallback() {

      public void onFailure(Throwable caught) {
        callback.onFailure(caught);
      }

      public void onSuccess() {
        callback.onSuccess(onInitialize());
      }
    });
  }

  /**
   * Add a column with a header.
   *
   * @param <C> the cell type
   * @param cell the cell used to render the column
   * @param headerText the header string
   * @param getter the value getter for the cell
   */
  @ShowcaseSource
  private <C> void addColumn(Cell<C> cell, String headerText,
      final GetValue<C> getter, FieldUpdater<ContactInfo, C> fieldUpdater) {
    Column<ContactInfo, C> column = new Column<ContactInfo, C>(cell) {
      @Override
      public C getValue(ContactInfo object) {
        return getter.getValue(object);
      }
    };
    column.setFieldUpdater(fieldUpdater);
    if (cell instanceof AbstractEditableCell<?, ?>) {
      editableCells.add((AbstractEditableCell<?, ?>) cell);
    }
    cellTable.addColumn(column, headerText);
  }
}
