module App {
    export class BaseController<T extends Entity>  {
        // my services
        searchService: SearchService;
        saveService: SaveService;
        authService: AuthService;
        url: UrlService;

        // my variables 
        searchRequest: SearchRequest;
        isUpdateMode: boolean;
        user: AccountInfo;

        // angular ui params
        stateService: angular.ui.IStateService;
        stateParams: angular.ui.IStateParamsService;

        // generic variables
        commandUrl: string;
        queryUrl: string;
        models: T[];
        model: T;

        constructor(
            $location: angular.ILocationService,
            $state: angular.ui.IStateService,
            $stateParams: angular.ui.IStateParamsService,
            url: UrlService,
            search: SearchService,
            save: SaveService,
            authService: AuthService,
            commandUrl: string,
            queryUrl: string
        ) {
            this.url = url;
            this.commandUrl = commandUrl;
            this.queryUrl = queryUrl;
            this.searchService = search;
            this.saveService = save;
            this.authService = authService;
            this.stateService = $state;
            this.stateParams = $stateParams;
            this.activate();
            var acc = this.authService.AccountInfo;
            //console.log(acc);
            if (acc && acc.IsAuth) {
                this.loadUser();
            }
        }

        loadUser(): void {
            var self = this;
            self.user = this.authService.AccountInfo;
        }
        
        goto(page: number): void {
            this.searchRequest.Page = page;
            this.search();
        }
        
        activate() {
            this.model = null;
            this.models = [];
            this.isUpdateMode = false;
            this.searchRequest = new SearchRequest("", "Modified", "False", "");
            this.search();
        }


        search(): void {
            var self = this;
            var successCallback = (response: SearchResponse): void => {
                console.log(response);
                self.models = <any>response.Models;
            };
            var errorCallback = (error: any): void => {
                console.log(error);
            };
            self.searchService.Search(self.searchRequest, self.queryUrl+"/Data").then(<any>successCallback, errorCallback);

            var countSuccessCallback = (response: SearchResponse): void => {

                self.searchRequest.TotalPage = Math.ceil(response.Data / 10);

            };
            var countErrorCallback = (error: any): void => {
                console.log(error);
            };
            self.searchService.Search(self.searchRequest, self.queryUrl+"/Count").then(<any>countSuccessCallback, countErrorCallback);
        }

        edit(p: T): void {
            this.model = p;
            this.isUpdateMode = true;
        }

        save(): void {
            var self = this;
            var successCallback = (response: BaseResponse): void => {
                self.activate();
            };
            var errorCallback = (error: any): void => {
                console.log(error);
            };

            self.saveService.Save(self.model, self.commandUrl).then(<any>successCallback, errorCallback);
        }

        update(): void {
            var self = this;
            var successCallback = (response: BaseResponse): void => {
                self.activate();
            };
            var errorCallback = (error: any): void => {
                console.log(error);
            };

            self.saveService.Update(self.model, self.commandUrl).then(<any>successCallback, errorCallback);
        }

        delete(id: string): void {
            var self = this;
            var successCallback = (response: BaseResponse): void => {
                self.activate();
            };
            var errorCallback = (error: any): void => {
                console.log(error);
            };
            self.saveService.Delete(id, self.commandUrl).then(successCallback, errorCallback);
        }


    }
}