package net.pokeranalytics.android.ui.adapter

import android.content.Context
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.util.TextFormat

/**
 * Base Interface to provide the RowRepresentable to the adapter
 */
interface RowRepresentableDataSource: EditableDataSource, DisplayableDataSource, SelectableDataSource {

    /**
     * Returns a prebuild list of rows
     */
    fun adapterRows(): List<RowRepresentable>?

    /**
     * Returns a [RowRepresentable] at position [Int]
     */
    fun rowRepresentableForPosition(position:Int): RowRepresentable?

    /**
     * Returns the number of [RowRepresentable] to display
     */
    fun numberOfRows(): Int

    /**
     * Returns the ordinal value of [RowViewType] at position [Int]
     */
    fun viewTypeForPosition(position:Int): Int

}

/**
 * Interface extending [RowRepresentableDataSource] to guide the implementation of a prebuild list of [RowRepresentable]
 * To do that, this interface overrides and provides a default implementation to specific methods of [RowRepresentableDataSource]
 */
interface StaticRowRepresentableDataSource: RowRepresentableDataSource {

    override fun rowRepresentableForPosition(position:Int): RowRepresentable? {
        this.adapterRows()?.let {
            return it[position]
        }
        throw IllegalStateException("Need to implement Data Source")
    }

    override fun numberOfRows(): Int {
        this.adapterRows()?.let {
            return it.size
        }
        throw IllegalStateException("Need to implement Data Source")
    }

    override fun viewTypeForPosition(position:Int): Int {
        this.rowRepresentableForPosition(position)?.let {
            return it.viewType
        }
        throw IllegalStateException("Need to implement Data Source")
    }

}



/**
 * Interface extending [RowRepresentableDataSource] to guide the implementation of a live list of [RowRepresentable]
 * To do that, this interface overrides and provides a default implementation to specific methods of [RowRepresentableDataSource]
 */
interface LiveRowRepresentableDataSource: RowRepresentableDataSource {
    override fun adapterRows(): List<RowRepresentable>? {
        return null
    }
}

/**
 * Custom class providing the value to display and how to display them
 */
class DisplayDescriptor(
	var boolValue: Boolean? = null,
	var stringValue: String? = null,
	var textFormat: TextFormat? = null,
	var actionIcon: Int? = null,
	var context: Context? = null) {
}

class UnmanagedRowRepresentableException(message: String) : Exception(message) {

}

/**
 * An interface used to provide RowRepresentableAdapter content and value in the form of rows
 *
 * Also returns the appropriate value for any RowRepresentable in the form of :
 * - string
 * - booleans
 * - actionIcon
 * to display the appropriate numericValues in graphical filterConditions, such as labels, textfields, switchs...
 */
interface DisplayableDataSource {

    fun contentDescriptorForRow(row: RowRepresentable): DisplayDescriptor? {
        return null
    }

    /**
     * Returns a boolean for a specific row
     */
    fun boolForRow(row: RowRepresentable): Boolean {
        return false
    }

    /**
     * Returns a int for a specific row
     */
    fun intForRow(row: RowRepresentable): Int {
        return -1
    }

    /**
     * Returns a localized string for a specific row
     */
    fun stringForRow(row: RowRepresentable, context: Context): String {
        return stringForRow(row)
    }

    /**
     * Returns a string for a specific row
     */
    fun stringForRow(row: RowRepresentable): String {
        return ""
    }

    /**
     * Returns a string for a specific row
     */
    fun statFormatForRow(row: RowRepresentable): TextFormat {
        return TextFormat("you should override this")
    }

    /**
     * Returns an action icon uniqueIdentifier for a specific row
     */
    fun actionIconForRow(row: RowRepresentable): Int? {
        return 0
    }

    /**
     * Returns whether the row, or its component, shoudl be enabled
     */
    fun isEnabled(row: RowRepresentable): Boolean {
        return true
    }

    /**
     * Returns whether the row, or its component, shoudl be enabled
     */
    fun isSelectable(row: RowRepresentable): Boolean {
        return true
    }
}

/**
 * An interface providing a way to describe how the edition of a [RowRepresentable] will be displayed
 */
interface EditableDataSource {
    /**
     * A list of [RowRepresentableEditDescriptor] object specifying the way the edition will be handled
     */
    fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor>? {
        return null
    }
}


/**
 * An interface providing a way to select a row
 */
interface SelectableDataSource {
    /**
     * A boolean to indicate if the row is selected or not
     */
    fun isSelected(row: RowRepresentable): Boolean {
        return false
    }
}