# coding: utf-8
import sys
import os
import ctypes
from .base import _LIB
from .base import _check_call, c_str

class XLearn(object):
	"""XLearn is the core interface used by python API."""
	def __init__(self, handle):
		"""Initalizes a new XLearn

		Parameters
		----------
		handle : XLearnHandle
		    'XLearn' handle of C API.
		"""
		assert isinstance(handle, XLearnHandle)
		self.handle = handle

	def __del__(self):
		_check_call(_LIB.XLearnHandleFree(self.handle))

	def __set_param(self, param):
		"""Set hyper-parameter for xlearn handle

		Parameters
		----------
		param : dict
		    xlearn hyper-parameters
		"""
		for (key, value) in param.items():
			if key == 'task':
				__check_call(_LIB.XLearnSetStr(self.handle, 
					c_str(key), c_str(value)))
			elif key == 'metric':
				__check_call(_LIB.XLearnSetStr(self.handle, 
					c_str(key), c_str(value)))
			elif key == 'log':
				__check_call(_LIB.XLearnSetStr(self.handle, 
					c_str(key), c_str(value)))
			elif key == 'lr':
				__check_call(_LIB.XLearnSetFloat(self.handle, 
					c_str(key), c_float(value)))
			elif key == 'k':
				__check_call(_LIB.XLearnSetInt(self.handle, 
					c_str(key), c_uint(value)))
			elif key == 'lambda':
				__check_call(_LIB.XLearnSetFloat(self.handle, 
					c_str(key), c_float(value)))
			elif key == 'init':
				__check_call(_LIB.XLearnSetFloat(self.handle, 
					c_str(key), c_float(value)))
			elif key == 'epoch':
				__check_call(_LIB(XLearnSetInt(self.handle, 
					c_str(key), c_uint(value))))
			elif key == 'fold':
				__check_call(_LIB(XLearnSetInt(self.handle, 
					c_str(key), c_uint(value))))
			else:
				raise Exception("Invalid key!", key)

	def setTrain(self, train_path):
		"""Set file path of training data.

		Parameters
		----------
		train_path : str
		   the path of training data
		"""
		_check_call(_LIB.XLearnSetTrain(self.handle, c_str(train_path)))

	def setTest(self, test_path):
		"""Set file path of test data.

		Parameters
		----------
		test_path : str
		   the path of test data.
		"""
		_check_call(_LIB.XLearnSetTest(self.handle, c_str(test_path)))

	def setValidate(self, val_path):
		"""Set file path of validation data.

		Parameters
		----------
		val_path : str
		   the path of validation data.
		"""
		_check_call(_LIB.XLearnSetValidate(self.handle, c_str(val_path)))

    def setOnDisk(self):
    	"""Set xlearn to use on-disk training"""
    	key = 'on_disk'
    	__check_call(_LIB.XLearnSetBool(self.handle, 
    		c_str(key), c_bool(True)))

	def setQuiet(self):
		"""Set xlearn to quiet model"""
		key = 'quiet'
		__check_call(_LIB.XLearnSetBool(self.handle, 
			c_str(key), c_bool(True)))

	def disableNorm(self):
		"""Disable instance-wise normalization"""
		key = 'norm'
		__check_call(_LIB.XLearnSetBool(self.handle, 
			c_str(key), c_bool(False)))

	def setLockFree(self):
		"""Set xlearn to use lock free training"""
		key = 'lock_free'
		__check_call(_LIB.XLearnSetBool(self.handle, 
			c_str(key), c_bool(True)))

	def disableEarlyStop(self):
		"""Disable early-stopping"""
		key = 'early_stop'
		__check_call(_LIB.XLearnSetBool(self.handle, 
			c_str(key), c_bool(False)))

	def setSign(self):
		"""Convert output to 0 and 1"""
		key = 'sign'
		__check_call(_LIB.XLearnSetBool(self.handle, 
			c_str(key), c_bool(True)))

	def setSigmoid(self):
		"""Convert output by using sigmoid"""
		key = 'sigmoid'
		__check_call(_LIB.XLearnSetBool(self.handle, 
			c_str(key), c_bool(True)))

	def fit(self, param, model_path):
		"""Check hyper-parameters, train model, and dump model.

		Parameters
		----------
		param : dict
		  hyper-parameter used by xlearn.
		model_path : str
		  path of model checkpoint.
		"""
		__set_Param(param)
		_check_call(_LIB.XLearnFit(self.handle, c_str(model_path)))

	def cv(self, param):
		""" Do cross-validation

		Parameters
		----------
		param : dict
		  hyper-parameter used by xlearn
		"""
		__set_Param(param)
		_check_call(_LIB.XLearnCV(self.handle))

	def predict(self, model_path, out_path):
		"""Predict output

        Parameters
        ----------
        model_path : str
          path of model checkpoint.
        out_path : str
          path of output result.
		"""
		_check_call(_LIB.XLearnPredict(self.handle, 
			c_str(model_path), c_str(out_path)))

def create_linear():
	"""
	Create a linear model.
	"""
	model_type = 'linear'
	handle = XLearnHandle()
	_check_call(_LIB.XLearnCreate(c_str(model_type),
		                          ctypes.byref(handle)))
	return XLearn(handle)

def create_fm():
	"""
	Create a factorization machine.
	"""
	model_type = 'fm'
	handle = XLearnHandle()
	_check_call(_LIB.XLearnCreate(c_str(model_type),
		                          ctypes.byref(handle)))
	return XLearn(handle)

def create_ffm():
	"""
	Create a field-aware factorization machine.
	"""
	model_type = 'ffm'
	handle = XLearnHandle()
	_check_call(_LIB.XLearnCreate(c_str(model_type),
		                          ctypes.byref(handle)))
	return XLearn(handle)

def hello():
	"""
	Say hello to user
	"""
	_check_call(_LIB.XLearnHello())

@@ -2313,20 +2313,17 @@
 ath)))%0A%0A
-    
+%09
 def setO

update python-package